使用重载 + 和 += 运算符销毁的临时变量
Temporary variable destroyed with overloaded + and += operator
>我得到一个段错误,因为我相信我的临时变量在运算符使用完之前就被销毁了(释放分配的内存)。这是我的主要代码:
int main(int argc, char *argv[])
{
Bcd b1 = Bcd(100), b2 = Bcd(20), b3 = Bcd(50);
b3 += b1 + b2;
return 0;
}
我在析构函数中放了一个 print 语句,输出如下:
sum
destroying 120
sum
segmentation fault
我不明白为什么会发生这种情况。临时变量 b1+b2 似乎在第二次按总和使用之前就被销毁了。临时变量 b1+b2 不应该在 main 的那行末尾之前有效吗?我是否正确地实现了运算符重载函数,或者我的代码是否存在我没有考虑的其他问题?
我的自定义类定义如下:
class Bcd
{
public:
Bcd();
Bcd(const char* num);
Bcd(const Bcd &num);
Bcd(const int num);
~Bcd();
int getLength() const;
Bcd& operator=(const Bcd &rhs);
Bcd& operator+=(const Bcd &rhs);
const Bcd& operator +(const Bcd &rhs) const;
std::string toString() const;
private:
//takes a character and places is at number[index]. If that index does
//not exist, allocates memory for that number and then sets number[index].
void modifyNumber(char num, int index);
char* number;
int length;
int size;
};
.c文件的重要部分在这里:
Bcd& Bcd::operator +=(const Bcd &rhs){
int minSize, i;
char result[2] = {0};
printf("sumn");
if(this->getLength() < rhs.getLength())
minSize = this->getLength();
else
minSize = rhs.getLength();
for(i = 0; i < minSize; i++) //SEGFAULT from accessing rhs.number[0]
this->modifyNumber(this->number[i] + rhs.number[i], i);
if(this->getLength() < rhs.getLength()){
for(;i < rhs.getLength(); i++)
this->modifyNumber(rhs.number[i], i);
}
else{
for(;i < this->getLength(); i++)
this->modifyNumber(this->number[i], i);
}
return *this;
}
const Bcd& Bcd::operator +(const Bcd &rhs) const
{
return Bcd(*this) += rhs;
}
Bcd::Bcd(const Bcd &num)
{
length = num.length;
size = num.size;
//allocate memory for number
number = new char[length];
for(int i = 0; i < length; i++)
number[i] = num.number[i];
}
这正是它应该发生的方式。可能更正确的说法是,被销毁的不是临时b1 + b2
,而是二进制+
实现中的临时Bcd(*this) += rhs
。
+
的实施
const Bcd& Bcd::operator +(const Bcd &rhs) const
{
return Bcd(*this) += rhs;
}
尝试返回绑定到临时的引用。临时在函数退出之前被销毁,引用保持挂起状态。调用方收到"死"引用。行为未定义。
这不是通过附加到临时的引用来延长临时生存期的上下文之一。
不能从二进制+
返回引用。您根本没有要返回引用的内容。相反,按值返回
Bcd Bcd::operator +(const Bcd &rhs) const
{
return Bcd(*this) += rhs;
}
此实现确实会返回一个临时的,该临时将用作b1 + b2
。而且这个临时不会过早地被摧毁。
一个问题是 operator+ 应该返回对象的副本,而不是引用。我认为您的代码创建了一个临时并返回其引用,这是一个很大的 NO。
编译器应该警告过您。如果使用GCC,则每次都使用-W -Wall。这将有很大帮助。
现在这很奇怪。我用我的 GCC 对此进行了测试,如果我在 -O2 或 -O3 优化的情况下进行编译,我只会收到警告。
相关文章:
- 函数参数变量总是需要 & 或 * 运算符吗?
- 在未初始化的变量上使用复合赋值运算符(+=, ..)不是C++中的UB?
- 如何正确返回带有成员变量的重载运算符++?
- 如何在不使用赋值运算符的情况下为动态变量赋值?
- 将内置类型变量传递给只有一个类类型参数的"+"运算符函数时自动类型转换的构造函数
- 变量地址的运算符[]是如何工作的
- 在C++中,为什么int可以使用new运算符初始化变量,而double不能
- 创建变量之间的运算符排列
- C++中重载复合赋值运算符不会更改变量
- 为什么通过通用引用运算符 (&&) 将变量的引用传递给 Varadic 模板函数失败?
- 为什么 ++ 运算符触发器返回对局部变量警告的引用
- 使用运算符将分隔的输入分隔>>变量
- 不太明白 & 运算符的地址在这个结构中做什么,以及它如何能够访问其他成员变量
- 为什么在 sizeof() 函数中与 * 运算符一起使用和不使用 * 运算符时,指向结构变量的指针大小会有所不同?
- 隐藏的成员变量不应在仅允许const访问的基类中突变,以便保留分配运算符
- 将删除运算符放置在何处以进行动态变量
- 重载运算符和静态成员变量的行为
- 为什么我的重载运算符+在向自身添加变量时会在返回时使"this"未初始化?
- 需要使用 Book* 头变量重载运算符,但不起作用
- 三元运算符:编译器不发出局部变量警告的返回引用