c ++继承和构造函数

时间:2011-01-21 14:16:44

标签: c++ inheritance constructor

class A {
public:
      A(int i): data(i) {cout << "A::A(" << i << ")" << endl;}
      A(const char* s): data(0) { cout << "A::A(" << s << ")"<< endl;}
      ~A() { cout << "A::~A()" << endl;}
private:
int data;
};

class B:public A {
public:
    B(const A& a): A(a){ std::cout << "B::B(const A& a)" << std::endl;}
     ~B() { std::cout << "B::~B()" << std::endl;}
};

int main() {
    B b0(0);
    B b1("abc");
return 0;
}

非常简单,有人可以解释输出为什么:

 A::A(0)
 B::B(const A& a)
 A::~A()
 A::A(abc)
 B::B(const A& a)
 A::~A()
 B::~B()
 A::~A()
 B::~B()
 A::~A()

6 个答案:

答案 0 :(得分:5)

B b0(0); - B没有这样的构造函数,所以编译器正在寻找一些构造函数,只需要一次转换就可以调用(一个隐式转换是允许的,2个不允许),所以它找到{{ 1}},因为B::B(const A& a)的构造函数只有一个参数,而且是A。这意味着,0可以转换为A::A(int i),因此创建临时int对象(并在创建B之后销毁)。所以,这就是为什么我们有

A

然后调用下一个: A::A(0) B::B(const A& a) A::~A() ,所以来了:

B b1("abc");

这与 A::A(abc) B::B(const A& a) A::~A() 完全相同,但此处为int

然后,两个对象都被破坏了,所以它们的析构函数以相反的顺序被调用,因为它们的构造函数被调用,那就是

char*

来自。

看起来很有问题,因为你没有超载 B::~B() A::~A() B::~B() A::~A() 并且你没有看到,它也被称为2次。

干杯(:


小编辑:不是A::A( const A& a),而是A::A() - 感谢Nim。

答案 1 :(得分:3)

您没有B的默认构造函数,因此编译器会找到最佳替代方法(即首先使用匹配的输入构造A,然后从中构造B。)

序列将是:

  • 使用A
  • 构建临时int
  • 使用此B
  • 构建A
  • 销毁A
  • (你没有A的复制构造函数,否则你会看到它也被抛出!)
  • 同样适用于字符串
  • 然后是基类/派生类析构函数的序列。

答案 2 :(得分:1)

构造一个临时A对象,然后通过const引用传递给B的构造函数,在那里使用copy ctor复制它(你没有用调试输出扩充它,所以你无法看到它进入B对象。

破坏按照相反的施工顺序进行;当他们被传递到的构造函数完成时,临时代表将被销毁。

答案 3 :(得分:1)

它使用B构造函数中的参数构造一个临时A,它用于初始化B :: A(通过默认的复制构造函数 - 因此A :: A(const A&amp;)没有输出) 在调用B :: B完成后,临时A被销毁。

答案 4 :(得分:1)

 1.  A::A(0)          <- temporary A in B b0(0) line
 2.  B::B(const A& a) <- construct b0, no visible call to A as you did not provide A(A const &)
 3.  A::~A()          <- destroy temporary A created in line 1        
 4.  A::A(abc)        <- temporary A in B b1("abc") line
 5.  B::B(const A& a) <- construct b1, no visible call to A as you did not provide A(A const &)
 6.  A::~A()          <- destroy temporary A created in line 4
 7.  B::~B()          <- b1 ~B() destructor
 8.  A::~A()          <- b1 ~A() destructor
 9.  B::~B()          <- b0 ~B() destructor
 10. A::~A()          <- b0 ~A() destructor

答案 5 :(得分:0)

我会试试:

 A::A(0)          // 1: construct an A using A(int) ctor in line 1 of main
 B::B(const A& a) // 2: construct a B passing the previously constructed A by const ref
 A::~A()          // 3: destruct the temporary A made in 1
 A::A(abc)        // 4:  construct an A using A(const char*) ctor in line 2 of main
 B::B(const A& a) // 5: construct a B passing the previously constructed A by const ref
 A::~A()          // 6: destruct the temporary A made in 4
                  // unwind the stack on exit of main
 B::~B()          // destruct B made in main line 2
 A::~A()          // destruct A inherited by B made in main line 2
 B::~B()          // destruct B made in main line 1
 A::~A()          // destruct A inherited by B made in main line 1