0

我试图弄清楚构造函数和析构函数何时被调用。示例代码:

 #include <iostream>
 using namespace std;

 class A{
 public:
     A();
     A(int);
     A operator+(const A& rhs) const;
     ~A();
 public:
     int x;
 };

 A A::operator+(const A& rhs) const
 {
     A r(x + rhs.x);
     cout<<"end A operator"<<endl;
     return r;
 }

 A::A(int y): x(y)
 {
     cout<<"Constructor A called"<<endl;
 }

 A::~A()
 {
     cout<<"Destructor A called"<<endl;

 }

 //////////

 class B{
 public:
     B();
     B(int);
     B operator+(B rhs) const;
     ~B();
 public:
     int x;
 };

 B B::operator+(B rhs) const
 {
     cout<<"beginning B operator"<<endl;
     return B(x + rhs.x);
 }

 B::B(int y): x(y)
 {
     cout<<"Constructor B called"<<endl;
 }

 B::~B()
 {
     cout<<"Destructor B called"<<endl;
 }

 int main()
 {
     cout<<"line 1 main()"<<endl;
     A a(1);
     cout<<"line 2 main()"<<endl;
     B b(2);

     cout<<"\nline 3 main()"<<endl;
     a = a + a;

     cout<<"\nline 4 main()"<<endl;
     b = b + b;

     cout<<"\nend of main"<<endl;
 }

所以当我调用它时,我得到输出:

 line 1 main()
 Constructor A called
 line 2 main()
 Constructor B called

 line 3 main()
 Constructor A called
 end A operator
 Destructor A called

 line 4 main()
 beginning B operator
 Constructor B called
 Destructor B called
 Destructor B called

 end of main
 Destructor B called
 Destructor A called

所以我当然理解输出的第一块。我明确地调用了这两个构造函数。第二个代码块,有一个构造函数,当你创建对象 r 时会调用它

 A r(x + rhs.x);
  1. 现在在这里调用 A 析构函数是因为 r 超出范围吗?这意味着从 A 运算符重载+中调用析构函数

然后是第三个输出代码块。在这行代码上调用构造函数 B。

 return B(x + rhs.x);
  1. 现在我最大的问题是为什么 B 析构函数在这里被调用两次?它是从哪里调用的 - main() 或 B 运算符重载+?
4

1 回答 1

0

在第二个代码块中,当变量 r 超出范围时调用 A 的析构函数。

在第三个代码块中,您实际上是在构造两个 B 对象。第一个是正在构造的,因为您按值传递 B,这会调用复制构造函数。编译器创建的默认复制构造函数不包含打印“已调用构造函数 B”的代码,因此您看不到在输出中调用了构造函数。正如您所说,在返回行上调用第二个构造函数,之后返回值和 rhs 变量都超出范围,并且为两个对象调用析构函数。

于 2013-10-02T02:21:17.653 回答