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()
答案 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