0

假设有两个类 Base 和 Derived

class Base
{
  private: 
int a;
}
class Derived:public Base
{
private:
int b;
 }
 int main()
{
 Derived d;
 cout<<sizeof(d);
  }

输出是 8。现在我的问题是当基类的成员变量是私有的并且派生类不能继承它时,为什么它在显示类的大小时包含数据成员?

4

6 回答 6

4

私有成员仍然存在,无论它们是否可以从外部访问 - 如果您实际上不需要这些成员,请不要将它们放在那里。

Private 并不意味着“如果不使用就删除它”——它只是意味着“你不能在课堂外使用它”。a通常,在类和真正的类中会有一些功能要使用b- 但由于这是一个最小化的示例,直到它不再是有用的示例,所以你没有那个。

当一个类从另一个类继承(私有)成员变量时,它们就是新类的一部分。如果它们是私有的,那只是意味着派生类不能直接使用它们——同样,在一个没有被最小化的真实类中,它会a在类 Base 中使用一个函数,并且在Derivedto use中使用一些函数b

于 2013-08-01T17:43:17.857 回答
3

如果您的基类中有非私有方法,他们可以访问和更改私有成员,因此成员仍然存在,因为任何子类都可以调用非私有方法。

私人意味着私人,而不是不包括。

为什么在没有方法的类中有私有成员?

于 2013-08-01T17:42:26.010 回答
2

当您继承一个类时,您的类内存布局是具有基类的所有内容,然后是您在新类中定义的所有内容。

您可以认为从 A 继承的 B 类是 A 加上 B 类的新增内容。

于 2013-08-01T17:45:13.593 回答
0

如果 base 没有任何方法来操作私有成员,则派生仍然无法访问成员,但是异常是 base 的朋友成员。如果要在派生中访问,请使私有成员受保护而不是私有。确保派生保留作为公共继承基础。请记住,派生类继承了所有基类:包括私有成员,但是,如果没有任何方法可以在基类中进行操作,私有成员 var 是无用的,除非构造函数对其进行了一些处理,这不是一个好的做法。

于 2013-08-01T17:48:43.007 回答
0

这个问题实际上与继承无关。有一个类只有私有字段,没有方法,也没有朋友。实际上,这些字段永远无法访问。为什么它不与任何地方的空类一样对待,包括继承?大多数编译器优化掉空的基类。

我不知道标准是否允许,但如果我写了一个编译器,我不会优化这些成员。谁知道呢,也许这个类需要与其他类的布局兼容,也许是用另一种语言编写的。不过,我会发出有关此类字段的警告。

于 2013-08-01T17:55:03.043 回答
0

这里的实际答案比看起来要复杂一些。

Derived不是标准布局类,因为最派生类和至少一个基类都具有非静态成员。因此,布局完全依赖于实现。您无法预测其成员的偏移量或类的大小。它可以等效于b直接跟随a的结构,或仅b在其中的结构,或在 69105 字节的填充之后具有a跟随的结构。b

因此,允许编译器检测到您无法访问Derived::a代码中的 a 的事实是一个红鲱鱼。

在实践中,我不知道任何编译器不会以通常的标准布局方式构建Derived为等效于带有b以下内容的结构a......但这只是因为它是实现编译器的最简单方法,而不是因为语言需要它。

于 2013-08-01T17:59:18.853 回答