我对C++中的复制构造函数感到困惑

I'm confused about copy-constructor in C++

本文关键字:构造函数 复制 C++ 我对      更新时间:2023-10-16

可能重复:
为什么在这种情况下不调用复制构造函数?

在下面的代码中,我构造了三个变量,a1、a2和a3。

C++Primer第476页中有一个例子:

string empty_copy = string();//copy-initialization

有人能帮我解释吗

1) 为什么a1和a2不是由复制构造函数和构造的

2) 我的代码中的初始化a2和书中的emptycopy之间有什么区别?

非常感谢!

#include<iostream>
using namespace std;
class A{
public:
    A(){}
    A(int v){}
    A(const A&x){
        cout<<"copy constructor"<<endl;
    }
};
A generateA(){
    return A(0);
}
int main(){
        cout<<"First:"<<endl;
        A a1=generateA();
        cout<<"Second:"<<endl;
        A a2=A(0);
        cout<<"Third:"<<endl;
        A a3=a1;
    return 0;
}

输出是(在Win7中的Visual Studio 2010和Ubuntu110.10中的g++下):

First:
Second:
Third:
copy constructor

这是由于返回值优化而导致的复制省略
编译器可以通过应用这样的优化来优化副本的生成。

A a1=generateA(); 
A a2=A(0); 

在以上两种情况下,编译器都可以取消创建临时对象,该对象是为保存返回值而创建的。

A a3=a1;

涉及用于构造a3的已存在命名对象a1,这涉及编译器必须进行且无法优化的复制构造函数调用。

编辑:回答评论中的问题。

您可以在编译过程中使用以下选项告诉编译器不要应用此优化:

对于GCC:

-fno-elide-constructors

对于MVSC:

/Od
  1. a1a2中不使用复制构造函数,因为在这两种情况下,您都在传递int,因此编译器使用您定义的A(int)构造函数。

  2. 你的例子和书中的例子的区别在于,书在堆栈上创建了一个实例(string()),因此得到了一个空副本,而在你的情况下,你使用的是一个现有的实例(a1)。两者都在使用复制构造函数进行初始化。

初始化a1时,会有一个整数参数(在工厂函数中给定)。对于a2,还可以传递一个整数。对于a3,你说a3=a1。这被解释为a3(a1),因为您定义了一个复制构造函数,所以它被调用。