【问题标题】:Argument passed by value or const reference in the constructor [duplicate]构造函数中通过值或常量引用传递的参数[重复]
【发布时间】:2016-02-05 06:35:02
【问题描述】:

下面的类哪个构造函数更好?

struct Foo
{ 
  Foo(const int& val):val_(val){} // constructor 1    
  Foo(int val):val_(val){} // constructor 2
  int val_;
};

在没有任何编译器优化的情况下,它们是只复制一次 val 还是构造函数 2 在初始化列表之前创建一个进一步的副本?

【问题讨论】:

    标签: c++ constructor pass-by-value pass-by-const-reference


    【解决方案1】:

    如果第一个构造函数被调用,传递给它的参数将不会被复制。 val 参数将绑定到传递的参数(通过引用复制)。

    如果调用第二个构造函数,则传递给它的参数将按值复制。

    两个构造函数的相同之处在于它们分别用val 初始化_val 并执行额外的按值复制。

    所以,没有任何优化,它看起来像这样:

                                                        Copies
    const int& constructor          1
    int constructor                          2
    

    【讨论】:

    • 这在技术上是正确的。但是,引用可能会被编译为指针,这意味着必须复制 指针 而不是值。
    【解决方案2】:

    基本上,构造函数 2 将复制两次:第一次在调用时,第二次在初始化时。 另一方面,您了解引用只不过是一个指针,并且随着被引用变量的大小减小到指针大小,构造函数 1 和 2 之间的成本不会降低。

    【讨论】:

    • 虽然其中一份副本可以省略。
    • 是的,这是我的猜测。所以第二次做一个额外的副本而不进行优化。所以对于大对象来说,第一个解决方案更好。或者,甚至更好的是直接传递一个 int&&。
    【解决方案3】:

    一般来说,您永远不需要通过 const 引用传递 int 变量。

    真正的问题是:你为什么在乎?如果Foo 是在具有很多迭代的循环内构造的,那么只有可测量的速度差异并且这几乎是该循环内发生的唯一事情 - 不太可能。

    所以只需使用#2。不是因为效率,而是因为它更简单。

    【讨论】:

    • int 只是为了寻求简单性。使用模板化参数而不是 int。如果编译器不执行复制省略,我的问题是关于复制的数量
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 2021-07-16
    相关资源
    最近更新 更多