【发布时间】:2019-11-18 16:51:53
【问题描述】:
您好,我一直在尝试分析以下使用操作重载的代码。
#include <iostream>
using namespace std;
#define DBG(str) cout << str << endl
class Integer {
int n;
public:
Integer(int _n) : n(_n) { DBG("A"); };
Integer(const Integer& i) : n(i.n) { DBG("B"); };
Integer& operator=(const Integer& i) { DBG("C"); n = i.n; return *this; };
Integer& operator+=(const Integer& i) { DBG("D"); n += i.n; return *this; };
friend Integer operator+(const Integer& a, const Integer& b);
friend Integer operator*(const Integer& a, const Integer& b);
friend ostream& operator<<(ostream& os, const Integer& i);
};
Integer operator+(const Integer& a, const Integer& b) {
DBG("E"); return Integer(a.n + b.n);
}
Integer operator*(const Integer& a, const Integer& b) {
DBG("F"); return Integer(a.n * b.n);
}
ostream& operator<<(ostream& os, const Integer& i) {
DBG("G"); os << i.n; return os;
}
int main() {
Integer n1(1), n2(2);
Integer n = 5 + n1 + 2 * n2;
cout << n << endl;
}
结果是……
A // constructor called when n1 is created
A // constructor called when n2 is created
A // when is this called?
A // when is this called?
F // called when 2 * n2 is operated
A // called when Integer(a.n * b.n) is created in the multiplication function
E // called when 5 + n1 is operated
A // called when Integer(a.n + b.n) is created in the addition function
E // called when (5 + n1) + (2 * n2) is operated
A // called when Integer is created in the addition function
G // called when n is printed using cout
5 // value of n
现在我最麻烦的是A的第三和第四个打印。在Integer n = 5 + n1 + 2 * n2;这句话中,对象n正在被创建并且正确的值被分配给n,所以应该调用一个复制构造函数?我认为应该发生的是应该调用构造函数来制作(5 + n1 + 2 * n2) 的临时对象,然后通过将其复制到n,应该调用复制构造函数。我理解错了什么?
你能解释一下发生了什么吗?提前谢谢你。
【问题讨论】:
-
让你的构造函数打印出
n的值来帮助追踪发生了什么。 -
你能在 DBG("A") 上放置一个断点并检查调用堆栈吗?
-
Integer n = 5 + n1 + 2 * n2;5被转换为Integer对象,该对象打印出A。2也是如此 -
您应该在调试器中单步执行代码以查看发生了什么。也就是说,我的猜测是第三个和第四个“A”标记来自将 5 和 2 转换为
Integer。您对创建n的复制构造函数是正确的。 -
您可以尝试使您的
Integer(int _n)构造函数explicit并查看编译器指向错误的位置。
标签: c++