在c ++ 14世界中寻求通用设计实践的一般指导。
这里const std::string& mName
是最合适的类型吗?它的副本最少,但是样式好吗?
我觉得ref暗示着某些其他别名,该别名在某个时刻处于或可能处于未知状态。
制作防御性副本是最好的样式吗?并改为使用const std::string mName
?还是在这种情况下将副本放在参数const std::string aName
中,并将&保留在成员字段中?
最常见的参数和成员存储做法是什么,哪些因素会以其他方式推动决策?
class Machine {
private:
const std::string& mName;
public:
Machine(const std::string& aName) : mName(aName) {
std::cout << &aName << std::endl;
std::cout << &mName << std::endl;
std::cout << std::endl;
}
};
int main() {
std::string x = "Number 1";
std::cout << &x << std::endl;
Machine m(x);
Machine m2("Number 6");
}
感觉更好,并且消除了我认为的临时副本?
class Machine {
private:
const std::string mName;
public:
Machine(const std::string&& aName) : mName(aName) {
std::cout << "1:: " << &aName << std::endl;
std::cout << "1:: " << &mName << std::endl;
}
Machine(const std::string& aName) : mName(aName) {
std::cout << "2:: " << &aName << std::endl;
std::cout << "2:: " << &mName << std::endl;
}
const std::string& name() const {
return mName;
}
};
int main() {
std::string x = "Number 1";
std::cout << &x << std::endl;
Machine m(x);
Machine m2("Number 6");
}
答案 0 :(得分:0)
如果要将构造函数参数存储在对象中,请按值获取对象。如果调用者传递了一个右值,它将被移动构造。如果用户传递了一个左值,无论如何,当您将其复制到对象中时,都必须创建一个副本。 >
这将产生最干净,最容易理解的代码:
class Machine {
private:
const std::string mName;
public:
Machine(const std::string aName) : mName(std::move(aName)) {
std::cout << "1:: " << &aName << std::endl; // this has been moved out of...
std::cout << "1:: " << &mName << std::endl;
}
const std::string& name() const {
return mName;
}
};
int main() {
Machine m(function_that_returns_a_string()); // move constructed all the way in - no copies made
string s;
Machine m2(s); // only one copy is made - when calling constructor, but it's then move constructed into the object
}
有时候对象仍然太昂贵而无法移动构造,此时使两个版本分别带有rvalue和lvalue引用将是一个胜利,但是在大多数情况下,上述样式是最好的方法。