在C ++中使用包装类时,比如
class myInt {
int _value;
public:
myInt( int value ) : _value( value );
int value() const { return _value; }
}
,与简单的int相比,是否有任何内存开销?
This answer说“如果没有虚拟功能”,但我想了解确切原因。
我查看了ISO / IEC 14882:2003的§10.3[class.virtual],其中说:“声明或继承虚函数的类称为多态类。”我知道这样一个类的对象不需要在它们中有一个vtable指针。
但我不明白它是如何得出的,因为它不需要任何内存开销。我可以创建一个派生自myInt的类,称之为myDerivedInt。我不能从myInt *到myDerivedInt *进行dynamic_cast吗?如果没有,为什么不呢?
答案 0 :(得分:2)
与简单的€int`相比,是否存在任何内存开销?
我会说不,但我不知道是否有保障。
我知道这样一个类的对象不需要在它们中有一个vtable指针。
如果在堆栈上创建了多态类对象,并且从不采用其地址,则编译器可能会发现它的函数永远不会被虚拟调用(动态调度),并且可能会从堆栈中删除虚拟表指针。 (这仅适用于每个案例。其他地方的类实例可能包括vtable指针)。这种优化会产生非常小的影响,所以我不担心它是否有效。通常,从具有vtable的类继承的类在其实例中也将具有vtable指针。
我无法从
dynamic_cast
到myInt*
进行myDerivedInt*
吗?
没有。如果它没有vtable则不会。换句话说,如果myInt
没有任何虚函数(或者没有从任何类继承),那么你dynamic_cast
MyInt*
MyDerivedInt*
就不能static_cast
。但是,您可以使用myInt
。
如果没有,为什么不呢?
因为dynamic_cast
中没有vtable。 vtable存储{{1}}所需的信息。
答案 1 :(得分:1)
但我不明白它是如何产生的,它不需要任何内存开销
那么,需要内存开销的唯一原因是如果必须在类中存储其他内容。它显然必须包含int
,因为它是其成员。但它并不需要vtable指针,而且C ++标准中没有任何其他内容要求其他任何东西必须包含在类中。这个类可以在没有内存开销的情况下实现,不是因为C ++标准说"这可以在没有内存开销的情况下完成"但是因为它不说"除了int
成员之外,该类还必须包含"。它没有指定任何需要引入开销的东西,因此可以避免开销。
当然,当编译器可以避免额外的开销时,他们通常会这样做,所以实际上这样的类没有内存开销。
答案 2 :(得分:0)
好的,在写这篇文章并完成最后一句话时,我找到了答案:
第5.2.7节[expr.dynamic.cast]第6条说:
否则,v应该是多态类型的指针或左值(10.3)。
我实际上在索引中看了“多态类型”,但是只提到了10.3中的出现......