C++中的运算符重载(复制构造函数和析构函数)

3
当我在C++中运行以下代码时:
#include <iostream>

using namespace std;

class Test
{
    public:
        string name;
        Test();
        Test(string pname);
        ~Test();
        Test operator+(Test right);
};

Test Test::operator+(Test right)
{
    Test neo_name;
    neo_name.name = name + "-" + right.name;
    return neo_name;
}

Test::Test()
{

}

Test::Test(string pname)
{
    name = pname;
}

Test::~Test()
{
    cout << "~ " << name << endl;
}

int main()
{
    Test D1("a");
    Test D2("b");

    Test D3;
    D3 = D1 + D2;

    return 0;
}

我注意到+运算符重载方法会破坏“a-b”(neo_name)和“b”(right)对象。
(1) ~ a-b
(2) ~ b
(3) ~ a-b
(4) ~ b
(5) ~ a

有人知道如何一次性销毁多个对象吗?

最终,我希望得到以下输出:

(3) ~ a-b
(4) ~ b
(5) ~ a

谢谢!


2
你可以通过采用 const& 参数来避免复制 b 对象(在任何大于几个字的结构体上,你都应该这样做)。一旦打开优化,a-b 的复制可能会被省略,虽然我认为没有保证这种方法。 - Silvio Mayolo
1
我知道我应该使用复制构造函数 - 是编译器在利用复制构造函数,而不是你。这就是为什么你看到了复制品。除了打印出~和一些文本之外,还要打印出this的值。你会发现被销毁的对象不是你明确创建的对象。 - PaulMcKenzie
3
通过进行上述所有更改,使其为 Test D3 = D1 + D2; 以给予复制省略的机会。通过这些更改,您将获得期望的结果。 - Igor Tandetnik
1个回答

1

您有几个地方可以清理。

改为这样:

    Test operator+(const Test & right);

您当前的实现需要进行不必要的复制。
接下来,在调用operator+方法时:
Test D3 = D1 + D2;

当你实例化时,几乎总是需要初始化基本规则。考虑一下必须发生的事情。

如果你这样做:

Test D3;
D3 = D1 + D2;

接下来,您将构建一个默认的D3,然后在紧接着的下一行调用operator+并复制D3。但是,如果您在一行上完成所有操作,编译器可以更加聪明,实际上要聪明得多。

尝试进行这些更改,看看是否感到更满意。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接