最佳答案
我现在正在学习 C + + ,尽量避免养成坏习惯。 据我所知,clang-clean 包含许多“最佳实践”,我尽可能地坚持它们(尽管我不一定理解 为什么,但它们被认为是好的) ,但我不确定我是否理解这里推荐的做法。
我使用了教程中的这个类:
class Creature
{
private:
std::string m_name;
public:
Creature(const std::string &name)
: m_name{name}
{
}
};
这导致一个来自 clang-clean 的建议,即我应该通过值而不是引用传递,并使用 std::move
。
如果我这样做,我得到的建议,使 name
一个参考(以确保它不会被复制每次)和警告,std::move
将不会有任何影响,因为 name
是一个 const
,所以我应该删除它。
我没有得到警告的唯一方法是完全移除 const
:
Creature(std::string name)
: m_name{std::move(name)}
{
}
这似乎是合乎逻辑的,因为 const
的唯一好处是防止扰乱原始字符串(这种情况不会发生,因为我是通过值传递的)。
但我在 CPlusPlus.com上看到:
但是请注意,在标准库中,move 意味着 move-from 对象处于有效但未指定的状态。这意味着,在执行这样的操作之后,只能销毁或分配移出对象的值; 否则访问该对象将产生一个未指定的值。
现在想象一下这个代码:
std::string nameString("Alex");
Creature c(nameString);
因为 nameString
是通过值传递的,所以 std::move
只会使构造函数中的 name
失效,而不会触及原始字符串。但这样做有什么好处呢?似乎内容只被复制了一次——如果我在调用 m_name{name}
时通过引用传递,如果我通过值传递(然后它被移动)。我知道这比通过值传递和不使用 std::move
要好(因为它被复制了两次)。
有两个问题:
std::move
并只调用 m_name{name}
有什么好处吗?