【问题标题】:Return value destructed in operator*在运算符中破坏的返回值*
【发布时间】:2017-01-04 07:09:18
【问题描述】:

我正在创建一个乘法运算符重载。它是这样声明的:

T operator*(const T & right);

它创建一个本地 T 对象,计算它的值并返回它。问题是当它被返回时,它似乎超出了范围并且它的析构函数被调用了。 AFAIK 它不应该发生,因为 return 语句应该创建一个副本。我没有提及它;该对象包含动态分配的内存,但它应该由我制作的赋值运算符处理。所以我有这样一行:

t1 = t2 * t3;

其中 t1t2t3T 对象。

我使用了我的调试器,operator* 中的本地临时 T 对象很好,但是返回的对象缺少动态分配的内容。

我想到的是 return 语句没有正确复制我的对象,因为它没有复制动态分配的内容,因为缺少复制构造函数。所以我做了一个这样的复制构造函数:

T(const T & arg)
{
    *this = arg;
}

所以它会使用我的赋值运算符。那就是事情开始变得奇怪的时候。每次调用复制构造函数时,我都会(几乎)发生堆栈溢出。而且在调试时,它似乎甚至没有调用赋值运算符。有什么问题?

【问题讨论】:

  • 无论您用文字描述什么,显然都没有正确编码。所以请发一个minimal reproducible example
  • 查找“三规则”或(如果使用 C++11 或更高版本)“五规则”。您所描述的使用动态分配某些资源的类是不遵循这些规则的典型症状......当您需要时。
  • 一般来说copy-ctor不应该调用operator=,而是有自己的实现。原因是 copy-ctor 正在初始化一个新实例,而 operator= 正在破坏现有实例并从另一个现有对象复制。我的猜测是您的 operator= 只是将分配的内存分配给“this”,(所以现在您有两个实例指向同一个内存)并且当右侧超出范围时,分配的内存会被正确删除. 现在,您剩下一个实例,该实例有一个指向已删除内存的悬空指针。发布您的 operator= 代码。
  • 另外,如果您没有彻底测试类的复制语义,为什么要实现将返回副本的运算符?仅在编写并测试了类的基础后才编写返回值的运算符。你在责怪operator *,但这不是问题所在。问题是你的类复制代码有问题。

标签: c++ scope return operator-overloading


【解决方案1】:

好的,谢谢回复。 3/5 规则 是问题所在。另外我有一种数据分配方法,在清理之前没有检查是否有数据分配。 已解决 :)

【讨论】:

    猜你喜欢
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    • 1970-01-01
    相关资源
    最近更新 更多