【问题标题】:const or ref or const ref or value as an argument of setter functionconst 或 ref 或 const ref 或 value 作为 setter 函数的参数
【发布时间】:2015-10-02 20:44:27
【问题描述】:

恒定性

class MyClass {
// ...
private:
    std::string m_parameter;
// ...
}

按值传递:

void MyClass::SetParameter(std::string parameter)
{
    m_parameter = parameter;
}

通过引用:

void MyClass::SetParameter(std::string& parameter)
{
    m_parameter = parameter;
}

通过常量引用:

void MyClass::SetParameter(const std::string& parameter)
{
    m_parameter = parameter;
}

按常量值传递:

void MyClass::SetParameter(const std::string parameter)
{
    m_parameter = parameter;
}

通过通用参考:

void MyClass::SetParameter(std::string&& parameter)
{
    m_parameter = parameter;
}

通过-const-universal-ref:

void MyClass::SetParameter(const std::string&& parameter)
{
    m_parameter = parameter;
}   

哪种变体最好(可能就 C++11 及其移动语义而言)?

PS。可能是函数体在某些情况下不正确。

【问题讨论】:

  • 你最后两个例子不是通用引用,它们是右值引用。
  • 答案可能会有所不同,具体取决于类的语义和您要实现的目标。如果不确定/一般情况 const ref 是最好的
  • @Andre 我想要实现的目标:它是一个简单的私人成员设置器。不管语义是什么。

标签: c++ c++11 parameter-passing


【解决方案1】:
  1. 按值传递:通常不好,因为可能会获取值副本。 (尽管移动构造函数可能会减轻)。

  2. 通过引用传递:不如函数可能修改传递的参数。此外,匿名临时无法绑定到引用。

  3. 通过const参考:仍然是最好的。没有复制,函数不能修改参数,匿名临时可以绑定到const引用。

  4. 通过&& 变体传递:目前没有意义,因为根据您编写函数体的方式没有移动语义。如果你写了std::move(m_parameter, parameter) 来代替赋值,那么在某些情况下这可能会胜过(3),编译器会选择更好的。

【讨论】:

  • 3.当通过 const 引用传递时,存在 ref 指向的值的副本。并且调用SetParameter("blahblahblah") 是临时的,然后被复制。
  • 我不同意在这种情况下按值传递并不好。无论如何都会有一个副本,因此在界面中制作它然后在其上调用std::move 可能比 const 参考版本更有效。
  • @TartanLlama pass-by-value 和 pass-by-const-ref 都有(理论上)比另一种更有效的情况。
  • @dyp 是的,这就是我说“可能是”的原因。我只是不同意按值传递不好,而不是认为这是最好的选择:)
【解决方案2】:

请参阅“有效 C++”Scott Meyers - 如果私有成员是内置类型,则按值传递比按引用传递(通常在编译器中作为指针实现)更有效。 STL 中的迭代器和函数对象也是如此,它们被设计为按值传递。否则,最好通过引用传递给 const。

【讨论】:

    猜你喜欢
    • 2021-12-13
    • 2018-01-20
    • 2016-12-07
    • 1970-01-01
    • 2014-04-16
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    • 2019-10-18
    相关资源
    最近更新 更多