c++操作符重载:用+=实现+
C++ operator overloading: implementing + with +=
操作符重载
显示以下列方式完成
class X {
X& operator+=(const X& rhs)
{
// actual addition of rhs to *this
return *this;
}
};
inline X operator+(X lhs, const X& rhs)
{
lhs += rhs;
return lhs;
}
我理解为什么参数lhs
需要按值取,但为什么我们需要按值返回它?我的意思是,以下内容有什么问题:
inline X& operator+(X lhs, const X& rhs)
{
lhs += rhs;
return lhs;
}
在函数内部,lhs
是一个新的X
,修改它不会影响两个操作数中的任何一个。因为这是新的,我们可以通过引用返回它,对吗?
返回对本地对象的引用的问题是调用者将在到达时接收到已经死亡的对象。
当你退出一个函数时,所有的局部变量都被销毁,所以你不能继续使用对它们的引用。
代码
const X& res = a+b;
如果操作符按值返回,
可以工作,因为语言中有一个特定的规则,规定绑定到引用的临时对象将保持有效,直到引用本身被销毁。
返回引用是不同的,因为对象的生命周期是被调用操作符的责任,而不是调用者的责任。因此,最终结果将是绑定到一个已经被销毁的对象的引用。
甚至X res;
res = a+b;
不能工作,因为当操作符调用返回时,对象在对res
赋值之前被销毁。复制构造函数X res = a+b;
也是如此。
如果您引用的值在退出函数后将不再存在,则永远不要返回引用。
在这种情况下,lhs
将一直存在直到函数返回。如果通过引用返回,该引用将"指向"一个不再存在的值,任何使用它的尝试都将导致未定义的行为。
这就是按值返回的原因。但是不用担心,许多编译器可以优化额外的复制,实际上它不是复制而是移动操作,所以即使它没有优化,"重"对象将被移动而不是复制,从c++ 11开始。
不是严格地回答问题,而是帮助理解参考文献…在返回引用时要非常谨慎,除非知道所引用的对象是稳定的。
这样做是不安全的
const std::string& doNothing(const std::string& x) {return x;}
您将在下面所示的第二个调用中断开
std::string baa = "sheep";
std::cout << doNothing(baa) << std::endl; // works
std::cout << doNothing("goat") << std::endl; // UNSAFE
这是因为第二个调用涉及隐式创建一个临时对象(std::string类型,使用构造函数调用string("goat")
)
name()
返回引用是安全的。class Person
{
private: std::string _name;
public: const std::string& name() { return _name; }
// other constructors and ways to set a _name
};
可以合理地保证类对象(因此它的内部_name
)将保留足够长的时间,以便引用对调用者有用。
- 复制/移动操作符是否可以安全地用于实现复制/移动分配操作符
- 如果操作符delete没有实现,为什么不编译它
- 一个更容易的拷贝分配操作符实现
- 通过调用Move赋值操作符实现Move构造函数
- 实现没有临时的转换操作符
- 在c++中实现shell的bash操作符
- c++操作符重载:用+=实现+
- c++:使用构造函数实现操作符
- 如何为代理类实现相等操作符函数
- 在c++中实现抽象接口的操作符重载
- 选择模板化的操作符实现
- 带有重载操作符的整型向量的实现无法正常运行
- 三法则.复制构造函数,赋值操作符实现
- 移动构造函数和赋值操作符,使用复制-交换习惯实现
- 根据move构造函数实现复制赋值操作符
- 如何在类中实现提取操作符
- 实现了在磁盘上存储值的容器的迭代操作符*
- c++中迭代器的前缀和后缀自增操作符重载实现的区别
- 实现指针转换操作符
- 为什么我要将复制构造函数和赋值操作符设为私有并在c++中实现呢?