22

在 C++ 中,与继承没有虚函数的基类相关的开销(内存/cpu)是多少?它和直接复制+粘贴班级成员一样好吗?

class a
{
public:
    void get();
protected:
    int _px;
}

class b : public a
{

}

和....相比

class a
{
public:
    void get();
protected:
    int _px;
}

class b
{
public:
    void get();
protected:
    int _px;

}
4

5 回答 5

31

与复制和过去相比,使用继承时可能会有轻微的内存开销(由于填充),请考虑以下类定义:

struct A
{
  int i;
  char c1;
};

struct B1 : A
{
  char c2;
};


struct B2
{
  int i;
  char c1;
  char c2;
};

sizeof(B1) 可能是 12,而 sizeof(B2) 可能只是 8。这是因为基类 A 分别填充到 8 个字节,然后 B1 再次填充到 12 个字节。

于 2009-08-14T21:29:11.360 回答
16

编译时间会稍微长一点,并且不会有额外的运行时开销。从优化器的角度来看,非虚拟方法与过程相同——它们可以只使用它们的内存地址来调用,而不需要虚拟方法表的开销。

于 2009-08-14T18:06:13.017 回答
3

如果您忘记了虚拟继承,那么拥有一个基类在内存和性能方面与拥有同一个类的成员是等价的。除了它有时会更好(例如,空类的大小至少为 1,但具有空基类通常没有开销)。

于 2009-08-14T19:06:35.843 回答
2

如果您可能有一个 Base* 类型的指针指向 Derived* 类型的对象,那么您可能需要一个虚拟析构函数并且您的原始前提不再适用。如果派生类有一个空的析构函数,并且它没有成员或者它们都是 POD 类型,你可以不使用虚拟析构函数,但通常最好安全地使用它并从一开始就将其设为虚拟。

编译器将生成对实现每个非虚拟成员函数的代码的直接调用,因此没有开销。

于 2009-08-14T19:14:31.507 回答
1

不是真的,它只是通过基类增加了内存。您可以在 C++ 常见问题解答中阅读更多内容

于 2009-08-14T18:05:20.350 回答