我的数学库大量使用接口。它的工作方式是我有一个接口,例如IVector,然后子类可以派生/实现它。原因是所有的载体都需要能够用另一个载体得到一个点积,而我不想因为某些原因而忘记它,所以把它放在那里是件好事。 但这些并不完全是接口。例如,获取向量大小的实现并不特定于每个向量结构,所以我只是把它放在IVector中。我还有一个从IVector接口调用函数的Vector命名空间,所以我也可以做Vector :: Dot(a,b),而不是a.Dot(b)。
这个设置工作得很好,但是存在一个很大的问题:实现接口的结构的大小更大。在做了一些测试后,我发现原因是纯虚函数:
@SpringBootApplication(scanBasePackages = { "com.myproject" })
@EnableJpaRepositories(basePackages="com.myproject.sprinbootapp.repository")
@EntityScan("com.myproject.sprinbootapp.model")
public class SpringbootAppWithDatabaseApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootAppWithDatabaseApplication.class, args);
}
}
@Service
public class TopicService {
@Autowired
private TopicRepository topicRepository;
private List<Topics> topics = new ArrayList<Topics>();
public List<Topics> getAllTopics(){
List<Topics> listOfTopics = new ArrayList<Topics>();
topicRepository.findAll().forEach(listOfTopics::add);;
return listOfTopics;
}
}
@Entity
public class Topics {
@Id
private String id;
private String name;
public Topics(){
}
getters and setters...
}
public interface TopicRepository extends CrudRepository<Topics, String> {
}
我认为原因是vpointer,但我不确定。
但即使它有意义发生,为什么在C#中实现接口时结构大小不会变得更大?这是我跑的一个测试(不是我得到与Marshal.SizeOf for Stuff相同的结果,但它不适用于接口):
#include <iostream>
using namespace std;
#define PRINT(thing) cout << thing << endl
struct A
{
virtual void F() = 0;
};
class B final : public A
{
};
class C
{
void F()
{
}
};
class D : public C
{
};
void main()
{
PRINT(sizeof(A)); // 4
PRINT(sizeof(B)); // 4
PRINT(sizeof(C)); // 1
PRINT(sizeof(D)); // 1
cin.get();
}
我认为接口只是纯抽象类的糖,但显然它们不是。我假设接口本身的大小更大,因为它们是引用类型。
那么为什么C#接口不占用更多内存而C ++纯虚函数占用更多内存呢?
这个问题给我带来了太多问题,我必须解决它。我最想知道的是我可以做些什么来使C#中的C#接口(所以我可以在没有类变大的情况下实现它们)。
答案 0 :(得分:1)
C#类的编组大小描述了存储它所需的字节数。这与界面无关。
C ++类的大小描述了实现它所需的内存量。
这是两个不同的概念,并解释你正在观察的差异