c + +通过值传递的复制构造参数 [英] c++ copy construct parameter passed by value

查看:171
本文介绍了c + +通过值传递的复制构造参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我想让freeFunct在对象a的副本上做非常量的东西。让我们说freeFunct是一个自由函数
,因为在实际代码的情况下,它需要许多不同的参数,
调用所有的几个公共函数,没有
点使它成为任何类的非静态成员函数。



三种不同的声明方式来到我的脑海。



我觉得第三种解决方案更糟。



前两者有什么区别吗?



有更好的东西吗?

  void freeFunct1(A a){
a.doStuff
}

void freeFunct2(const A& a){
A b = a;
b.doStuff();
}

/ ** freeFunct3的用户预期为
*,以提供其变量的副本:
* {
* A b = a;
* freeFunct3(b);
*}
* /
void freeFunct3(A& a){
a.doStuff();
}


解决方案

如果自由函数的语义只修改其自己的对象,则不要执行 freeFunct3



第二, freeFunct1 freeFunct2 之间存在与移动优化相关的差异 [C + +11],异常安全以及潜在的代码大小



/ code>(通过引用到const):


  1. 它将总是构造一个参数的新副本如果 A 的复制结构抛出异常,它将抛出
  2. 它将在函数正文内部(即使该函数从多个不同位置调用)在内扩展一次。

使用 freeFunct1 (取值):


    < ++ 11]如果 A 有移动构造函数,并且传递一个右值(例如如果 A的复制(或移动)构造,则调用 freeFunct1(A(args)) 抛出异常,它会在调用网站上
  1. 如果 A 的复制(或移动)构造函数是内联的,它将在每个调用网站上多次展开

或者,您可以对lvalue / rvalue引用重载以避免不必要地复制rvalues:

  void freeFunct4(const A& ; a){
A b = a;
b.doStuff();
}
void freeFunct4(A& a){
a.doStuff();
}


I want freeFunct to do non const stuff on its own copy of object a.

Let's say that freeFunct is required to be a free function because in real code cases it takes many different parameters, calls several public functions from all of them and there is no point in making it a non-static member function of any class.

Three different ways of declaring it come to my mind.

I have the feeling that the third solution is the worse.

Is there any difference between the first two?

Is there something better?

void freeFunct1(A a){
    a.doStuff(); 
}

void freeFunct2(const A& a){
    A b = a; 
    b.doStuff(); 
}

/**users of freeFunct3 are expected 
 *to give a copy of their variable: 
 *{
 *    A b = a; 
 *    freeFunct3(b); 
 *}
 */
void freeFunct3(A& a){
    a.doStuff(); 
}

解决方案

First, as already said, don't do freeFunct3 if the semantics of the free function is to only modify its "own" object.

Second, there are differences between freeFunct1 and freeFunct2, relating to move optimization [C++11], exception safety, and potentially code size.

With freeFunct2 (taking by reference-to-const):

  1. It will always construct a new copy of the argument, never move it [C++11].
  2. If the copy construction of A throws an exception, it will throw inside the body of the function.
  3. If A's copy constructor is inlined (and the function is not), it will be expanded once, inside the body of the function (even if the function is called from multiple different places).

With freeFunct1 (taking by value):

  1. [C++11] You can avoid a copy if A has a move constructor and you pass an rvalue (e.g. call freeFunct1(A(args))).
  2. If the copy (or move) construction of A throws an exception, it will throw at the call site.
  3. If A's copy (or move) constructor is inlined, it will be expanded multiple times, at each call site.

Alternatively, you can overload on lvalue/rvalue reference to avoid unnecessarily copying rvalues:

void freeFunct4(const A& a){
    A b = a; 
    b.doStuff(); 
}
void freeFunct4(A&& a){
    a.doStuff(); 
}

这篇关于c + +通过值传递的复制构造参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆