我试图熟悉C ++中的构造函数和析构函数。下面的程序只是创建一个复数,在stdio上打印并退出。我创建了3个对象(1.使用默认构造函数,2。使用显式构造函数,第三个使用复制构造函数。在退出之前,它破坏了4个对象。为什么我的程序下面会破坏比构造函数创建的更多的对象?
#include <iostream>
using namespace std;
class complex
{
private: float a; float b;
public: float real(){return a;};
float imag(){return b;};
complex(){a=0.0; b=0.0;cout << "complex no. created."<<endl;};
complex(float x, float y){a=x; b=y;};
~complex(){cout << "complex no. with real part " << this->real() << " destroyed" << endl;};
void display(){cout << a << '+' << b << 'i';}
friend ostream& operator<< (ostream & sout, complex c)
{
sout << c.a << '+' << c.b << 'i' << "\n";
return sout;
}
};
main()
{
complex c1;
complex c2(1.0,1.0);
c1.display();
cout << endl;
c2.display();
cout << endl;
cout << c2.imag() << endl;
complex c3 = c2; // this uses the default 'copy constructor'
c3.display();
cout << endl;
cout << c2;
}
我得到的输出是:
complex no. created.
0+0i
1+1i
1
1+1i
1+1i
complex no. with real part 1 destroyed
complex no. with real part 1 destroyed
complex no. with real part 1 destroyed
complex no. with real part 0 destroyed
为了完成,我在CC和g ++编译器上尝试了这个。它们都表现相同。
答案 0 :(得分:8)
您的类有另一个构造函数 - 隐式定义的复制构造函数。它不会打印任何东西,但是对象会随之构建。
定义你自己的拷贝构造函数,在其中打印一些东西 - 然后你会看到构造函数和析构函数排成一行。
您的operator<<
按值complex
,因此每当您调用它时都会创建一个临时值。这就是“额外”构造函数/析构函数对的来源。
答案 1 :(得分:8)
friend ostream& operator<< (ostream & sout, complex c)
按值传递复数,因此正在创建另一个复合体。
将函数参数更改为
friend ostream& operator<< (ostream & sout, const complex& c)
这将通过引用传递复杂(保存正在创建和销毁的副本)。
const限定符意味着你的函数不会修改c的内容。 如果你的函数没有const限定符,它就不会接受常量的复杂对象,所以下面的代码会导致错误(这不是你想要的)。
const complex a_constant_complex(1.0,1.0);
cout << a_constant_complex << endl;
关于您的代码的其他说明
此外,如果可能的话,也不要习惯使用'using namespace std;'。将整个std命名空间拉入全局命名空间并不是一件好事。
尾随'&lt;&lt;运算符中的“\ n”'&lt;&lt;也不应该在那里。运营商的目的&lt;&lt;是将自己发送到流,如果调用者想要一个新行,他们将添加&lt;&lt;像我在我不断的例子中所做的那样。
答案 2 :(得分:2)
添加复制构造函数,插入断点并观察:)
complex(complex ©complex)
{
cout << "hello from the copy constructor." << endl;
*this = copycomplex;
};