4

我正在尝试熟悉 C++ 中的构造函数和析构函数。下面的程序简单地创建一个复数,在标准输入输出上打印它并退出。我创建了 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++ 编译器上尝试过这个。而且他们俩的行为都是一样的。

4

3 回答 3

8

你的类有另一个构造函数 - 一个隐式定义的复制构造函数。它不打印任何东西,但是仍然用它构造对象。

定义你自己的复制构造函数,在里面打印一些东西——然后你会看到构造函数和析构函数排成一行。

您按价值operator<<取值complex,因此每当您调用它时都会创建一个临时的。这就是“额外”构造函数/析构函数对的来源。

于 2013-09-23T02:15:57.127 回答
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 命名空间拉到您的全局命名空间中并不是一件好事。

并且操作符<< 中的尾随 '<< "\n"' 也不应该在那里。operator<< 的目的是将自己发送到流中,如果调用者想要在它之后换行,他们将添加一个 << endl 就像我在我的常量示例中所做的那样。

于 2013-09-23T02:19:43.927 回答
2

添加复制构造函数,插入断点并观察:)

complex(complex &copycomplex)
{
    cout << "hello from the copy constructor." << endl;
    *this = copycomplex;
};
于 2013-09-23T02:44:42.373 回答