【问题标题】:does a derived class object contain private members of the base class? What does it look like in memory?派生类对象是否包含基类的私有成员?它在记忆中是什么样子的?
【发布时间】:2015-03-29 10:45:19
【问题描述】:
class base{
private:
  int a;
public:
  int b;
  void setData(){
    a = 10; b = 5;
  }
};
class derived: public base{
private:    
   int c;
public:
  // b is inherited
};

void main(){
  derived D1;

  D1.setData();
}

我了解到私有成员不会被继承。因此,派生类对象中不存在私有变量 a(在基类中)。我的问题是 当 D1.setData() 被调用时,如果 a 不存在,它如何为 a 赋值? 我很确定我的这个概念是错误的,所以有人可以解释一下它是如何工作的吗?创建派生类对象时,是否也创建了基类成员?

【问题讨论】:

  • 它们是继承的,但是它们是不可访问的。尝试调试,在对象周围设置断点并在运行时查看它,您将了解它的外观!

标签: c++ class inheritance base derived


【解决方案1】:

我了解到私有成员不会被继承。

当然它们是继承的:否则,所有需要这些私有变量的基类成员函数都会被破坏。尽管继承类无法访问私有成员,但基类保留对它们的完全访问权限。

有人能解释一下这是如何工作的吗?

继承类derived的布局包括一个存放基类私有成员a的地方。基类的所有方法都可以访问base::a。同时,派生类仍然无法访问它:任何从derived 访问a 的尝试都会导致编译时错误。

【讨论】:

    【解决方案2】:

    私有成员变量被继承,但不能被外部访问。继承的内存模式很简单:

    class base {
        int x;
    };
    
    class subclassCpp : public base {
        int y;
    };
    
    class subclassCStyle {
        base a;
        int y;
    };
    

    现在,subclassCppsubclassCStyle 具有完全相同的内存模式,无论私有/受保护状态等如何。这应该说明内存是如何布局的。

    对于另一个问题,“在创建派生类对象时,是否也创建了基类成员?”

    答案是肯定的,构造函数总是在基类上调用。如果您不自己添加它,则会自动调用默认构造函数。如果基类没有默认构造函数,它不会让您创建一个子类构造函数,该构造函数不能正确调用初始化基类所需的任何构造函数。因此,只要执行了子类中的构造函数,就没有合法的方法可以在创建子类时得到尚未初始化的基类。

    【讨论】:

    • 它不应该被称为subclassCStyle,因为这仍然是完成的,并且它在 C++ 或其他 OO 语言中的使用。您可以继承或聚合一个类,两者都是不同的东西,在制作对象模型时可以有不同的解释。如果 B 类继承自 A 类,则表示 B 类的对象是 A 类的一种对象,例如:圆形是一种几何形状。如果 B 类聚合 C 类,这意味着 B 类的对象包含 C 类的对象,例如:圆包含一个点(原点)
    • C 风格的多态性/继承是可搜索的术语。现在很明显,将一个类作为一个字段放在另一个类中是非常普遍和有效的。但试图在 C++ 中重新发明多态转换并不是真正值得认可的。在您描述的模式中,您为什么不通过访问器或访问字段而不是强制转换为基础来获取包含的对象?这就是为什么您的示例不是 C 样式继承的原因。
    猜你喜欢
    • 1970-01-01
    • 2014-11-27
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    相关资源
    最近更新 更多