【问题标题】:C++ inheritanceC++ 继承
【发布时间】:2016-03-02 23:13:29
【问题描述】:

我有一个关于继承的 C++ 问题。

class X{
public:
 X()
 {
   cerr << "X()|";
 }
 X(const X& c)
 {
   cerr << "X(const X&)|";
 }
 ~X()
 {
   cerr << "~X()|";
 }
 X& operator=(const X& c)
 { 
   cerr << "X::op=|"; return *this;
 }
};

class B{
public:
 B()
 {
   cerr << "B()|";
 }
 B(const B& c):x1_(c.x1_)
 {
   cerr << "B(const B&)|";
 }
 virtual ~B()
 {
   cerr << "~B()|";
 }
 B& operator=(const B& c)
 { 
   cerr << "B::op=|"; 
   x1_=c.x1_;
   return *this;
 }
private:
 X x1_;
};

class D:public B{
public:
 D()
 {
   cerr << "D()|";
 }
 virtual ~D()
 {
   cerr << "~D()|";
 }
 private:
 X x2_;
};

问题 1:

当我运行B *pb = new B() 时,结果是X()|B()|

当我运行D *pd = new D() 时,结果是X()|B()|X()|D()|

这是为什么呢? B 不是 X 的子类。

问题 2:

首先我运行D d(*pd)

然后我运行*pd = d,结果是B::op=|X::op=|X::op=|

然后我运行*pb = *pd,结果是B::op=|X::op=|

为什么*pd = d 有两个X::op=|*pb = *pd 只有一个X::op=|

【问题讨论】:

    标签: class c++11 inheritance


    【解决方案1】:

    1) B 包含一个私有实例 X(名为 x1_)。该实例将在构造B 的过程中构造。首先调用基(在任何)的构造函数,然后是成员,然后是包含类。所以构造一个B 将首先调用X 的构造函数,然后是B 的构造函数。构造D将首先构造B(构造B的私有X,然后调用B的构造函数),然后构造D的私有X(命名为@ 987654335@),然后调用D的构造函数。

    2) *pd = d 分配一个D。由于D 包含两个X 实例(D 的名为x2_ 的私有成员和从B 继承的一个),编译器生成的D 赋值运算符将为两者调用X::operator=() . *pb = *pd 进行对象切片,并且只调用 B::operator=(),而不管 *pd 的类型是 D

    【讨论】:

      【解决方案2】:

      A1) B *pb = new B() 结果:X()|B()| 因为要构造 B,必须首先构造 X 的对象。这是因为B 私下包含 X

      A2) 我不知道你在问什么!请详细说明。

      编辑:

      当您执行*pd = d 时,您将d 分配给D (*pd) 的一个实例。现在,D 包含一个私有 X,并且还继承自 B(其中包含另一个 X)。因此,两次调用X 的赋值运算符。

      现在,当您执行*pb = *pd 时,您将*pd 分配给B (*pb) 的一个实例。由于继承,D 的类型为 B。因此,仅将特定于 B 的内容分配给 *pb,跳过仅属于 D 对象 (object slicing) 的内容。因此,只需调用X 的赋值运算符。

      【讨论】:

      • 为什么 *pd = d 有两个 X::op=|而 *pb = *pd 只有一个 X::op=|?
      猜你喜欢
      • 2015-04-19
      • 2012-10-30
      • 2023-04-06
      • 2010-11-05
      • 1970-01-01
      • 2017-03-31
      • 2012-02-13
      • 2015-12-09
      • 1970-01-01
      相关资源
      最近更新 更多