包装类的内存开销

时间:2014-08-10 14:48:10

标签: c++ memory-management wrapper

在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吗?如果没有,为什么不呢?

3 个答案:

答案 0 :(得分:2)

  

与简单的€int`相比,是否存在任何内存开销?

我会说不,但我不知道是否有保障。

  

我知道这样一个类的对象不需要在它们中有一个vtable指针。

如果在堆栈上创建了多态类对象,并且从不采用其地址,则编译器可能会发现它的函数永远不会被虚拟调用(动态调度),并且可能会从堆栈中删除虚拟表指针。 (这仅适用于每个案例。其他地方的类实例可能包括vtable指针)。这种优化会产生非常小的影响,所以我不担心它是否有效。通常,从具有vtable的类继承的类在其实例中也将具有vtable指针。

  

我无法从dynamic_castmyInt*进行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中的出现......