我写过这个类和驱动函数:
#include <cstdlib>
#include <iostream>
using namespace std;
class Weight {
int grams;
int kilograms;
public:
Weight(int kg, int g) : kilograms(kg), grams(g) {
}
~Weight() {
cout << "Destructor " << this->kilograms << " " << this->grams << "\n";
}
friend Weight operator+(const Weight& a, const Weight& b);
Weight operator+(const Weight& w) const {
cout << "member operator+\n";
int newKg = this->kilograms + w.kilograms;
int newG = this->grams + w.grams;
if (newG >= 1000) {
newG -= 1000;
newKg += 1;
}
return Weight(newKg, newG);
}
Weight operator+(const int addition) const {
cout << "operator+int" << endl;
int newKg = this->kilograms;
int newG = this->grams + addition;
if (newG >= 1000) {
newG -= 1000;
newKg += 1;
}
return Weight(newKg, newG);
}
Weight operator+(const double addition) const {
cout << "operator+double" << endl;
int newKg = this->kilograms + ((int) addition);
int newG = this->grams + (1000 * (addition - ((int) addition)));
if (newG >= 1000) {
newG -= 1000;
newKg += 1;
}
return Weight(newKg, newG);
}
Weight& operator=(const Weight & w) {
cout << "Assignment operator\n";
this->grams = w.grams;
this->kilograms = w.kilograms;
return *this;
}
void print() {
cout << "Weight is: " << this->kilograms << " Kilograms and " << this->grams <<
" Grams\n";
}
};
Weight operator+(const Weight& a, const Weight& b) {
cout << "Friend plus\n";
int newKg = a.kilograms + b.kilograms;
int newG = a.grams + b.grams;
if (newG >= 1000) {
newG -= 1000;
newKg += 1;
}
return Weight(newKg, newG);
}
int main(int argc, char** argv) {
Weight m(90, 900);
m = m + 1.1;
m = m + m;
m.print();
return 0;
}
这是输出:
operator+double
Assignment operator
Destructor 92 0
Friend plus
Assignment operator
Destructor 184 0
Weight is: 184 Kilograms and 0 Grams
Destructor 184 0
为什么在调用两个赋值运算符后两次调用析构函数? (即输出中的第三行和第六行)。
我知道这些可能是用于添加的临时变量,但是规则或C ++规范是什么?
感谢。
答案 0 :(得分:3)
因为operator+
确实创建了一个临时对象,它是操作的结果,并在赋值后被丢弃。
考虑operator+
:Weight operator+(const double addition) const
的自己签名。这将按值返回Weight
对象实例。这不是引用,也不是指针。它是一个事实上的新对象,用于保存m + 1.1
的结果,而不首先更新m
的值(与operator+=
不同)。从你自己的代码中看,这一点更加明显:return Weight(newKg, newG);
- 在这里创建了一个新对象,它需要被销毁。
然后将此临时值分配到m
,然后临时对象在移出范围时被销毁。
作为旁注,你在这里看到的也是一种优化(标准优化称为&#34;返回值优化&#34;)因为这种情况的明确行为将是临时的构建return
的堆栈帧内的operator+
语句中的值,然后是调用函数main
的堆栈帧中的值的复制构造,然后是对象的销毁在operator+
堆栈框架中。然后main
中的值将进入赋值运算符,然后也被销毁。您的编译器只是优化了此代码,以直接在调用函数的堆栈帧上构造返回值,从而节省了额外的临时对象。