2013-10-15 103 views
4

因此private基类中的成员也在继承类中,但不能在其中访问,对吧?
它们实际上是在分配给继承对象的内存中吗?
为什么私人会员继承?

+2

继承是一种“is-a”关系,所以是的,基类所需的所有内存都是子类中所需的。 – clcto

回答

7

它们实际上在分配给继承对象的内存中吗?

是的,他们需要存在。私有成员是基类实现细节的一部分。没有他们,一般来说,基类将无法运作(这就是他们首先存在的原因)。

将它们设置为私有只允许基类创建其实现,但不会将其公开给任何人,包括子类。

+1

除了这个好的答案,我会说,基本上当你有一个基类MyBase例如,它是由一些类MyDerived继承(无论如何 - 公共,私有或保护),并且当你创建一个对象类型为MyDerived,在内存中的对象布局中,实际上会有一个MyBase类型的对象。所以简单地说:MyDerived类型的每个对象都有一个MyBase类型的对象。 – BlackCat

+0

@BlackCat - Re *简单地说:MyDerived类型的每个对象都有一个MyBase类型的对象。* Diamond继承。假设B和C各自继承了A,D从B和C继承。至少嵌入在D类实例中的B和C对象中的一个不会在它们“内部”包含一个A对象。 –

+0

@David:B和C都有一个指向普通(共享)基类A对象的指针。尽管他们不一定有A级对象,但他们的行为与他们的行为一样。 – Tomek

6

是的。刚刚例如,你可以使用一个公共职能从操纵私人数据的基类,甚至在派生类的一个实例:

class Base { 
    int x; 
public: 
    Base() : x(0) {} 
    void inc() { ++x; } 
    void show() { std::cout << x << "\n"; } 
}; 

class Derived : public Base { 
}; 

int main() { 
    Derived d; 
    d.show(); 
    d.inc(); 
    d.show(); 
} 

有了一个正常的编译器,它必须显示:

0 
1 

...显示Base对象中的数据存在于Derived对象中,即使它不是(直接)可访问的。如果编译器可以确定它可以以某种方式为程序产生正确的可观察行为,即使没有包含以下内容的私有部分,也可以使用“as-if”规则:基类,那么它可以自由地这样做。最明显的例子就是如果你在基类中包含了一些在实践中从未使用过的东西(成员函数或数据)。

+0

如果你编译成一个可分发的DLL,你怎么知道一个特定的成员函数是否没有被使用? – TemplateRex

+0

@TemplateRex:有可能它不能,所以在这种情况下,它很可能不会忽略它。 –

+0

我认为一次派生类的根本问题在于它可以被再次继承,而潜在的孩子是一个开放的集合。因此,除非'Derived'被标记为'final',否则我不认为编译器可以将as-if规则应用于其类布局。最重要的是,这组未来的呼叫者也是一个开放的集合。 – TemplateRex

2

是它们是,

当要构造的派生类的对象的所有基类的,首先被构造为好。到达派生构造函数体前

class Base 
{ 
int x; 

public: 
    Base(int px) 
    : x(px) 
    { 
    } 
}; 

class Derived : public Base 
{ 
int y; 
public: 
    Derived(int px, int py) 
    : y(py), Base(px) 
    { 
    } 
}; 

这个例子编译和作品,BASE是初始化(构造函数):

考虑这个例子。