【发布时间】:2021-12-19 19:24:20
【问题描述】:
我遇到了this 对如何编写 C++ getter/setter 的回答,作者暗示当涉及到面向值的属性时,标准库中的 setter 像这样使用std::move()...
class Foo
{
X x_;
public:
X x() const { return x_; }
void x(X x) { x_ = std::move(x); }
}
(直接取自上述答案的代码)
...利用移动运算符(如果指定),可能会提高性能。
这本身对我来说很有意义 - 值在通过值传递给方法时被复制一次,因此如果可以移动它们,则无需再次将它们复制到属性。但是,我对 C++ 的了解还不足以确定在所有情况下这样做都是安全的。
按值传递参数是否总是进行深层复制?还是取决于对象?考虑到 std::move() 据称“向编译器发出信号,我不在乎移动的对象会发生什么”,如果我打算保留原始对象,这可能会产生意想不到的副作用。
如果这是一个众所周知的问题,我深表歉意,我正在学习 C++,我真的很想深入了解这门语言。
【问题讨论】:
-
是的,这是编写 setter 的好方法,但我认为我在标准库中没有见过它。 “如果我打算保留原始对象,会出现意外的副作用” 不,你不这样做,因为原始对象是
X x,它只存在于 setter 内部,无法在外部访问。 -
我建议你阅读 Scott Meyer 写的 Modern Effective C++,深入了解
std::move和陷阱 -
按值传递,参数通过复制或移动获取参数(取决于调用者和对象的能力)。如果对象具有值语义,那么它会在需要时进行深层复制。对象可以具有您为其编程的任何移动后置条件;大多数 C++ 标准库对象将处于有效但未指定状态,其中一些像 std::vector 或 std::unique_ptr 具有更强的后置条件保证。
标签: c++ getter c++-standard-library