成员和参数存储的通用做法

时间:2018-11-07 01:30:58

标签: c++

在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");
}

1 个答案:

答案 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引用将是一个胜利,但是在大多数情况下,上述样式是最好的方法。