简体   繁体   English

C ++为什么复制构造函数被调用?

[英]C++ Why was the copy constructor called?

class A {
public:
    A() {}
    A(const A& a) { cout << "A::A(A&)" << endl; }
};

class B {
public:
    explicit B(A aa) {}
};

int main() {
    A a;
    B b(a);
    return 0;
}

Why does it print "A::A(A&)"? 为什么打印“A :: A(A&)”?

When was the copy constructor for "A" called? 什么时候“A”的复制构造函数被称为? And if the code calls the copy constructor, why can I remove the copy constructor without creating a compilation error? 如果代码调用了复制构造函数,为什么我可以在不创建编译错误的情况下删除复制构造函数?

B(A aa) takes an A by value, so when you execute B b(a) the compiler calls the copy constructor A(const A& a) to generate the instance of A named aa in the explicit constructor for B . B(A aa)采用A by值,因此当您执行B b(a) ,编译器调用复制构造函数A(const A& a)以在Bexplicit构造函数中生成名为aaA实例。

The reason you can remove the copy constructor and have this still work is that the compiler will generate a copy constructor for you in cases where you have not also declared a move constructor. 您可以删除复制构造函数并使其仍然有效的原因是,在您尚未声明移动构造函数的情况下,编译器将为您生成复制构造函数。

Note: The compiler generated copy constructor is often not sufficient for complex classes, it performs a simple member wise copy, so for complex elements or dynamically allocated memory you should declare your own. 注意:编译器生成的复制构造函数通常不足以用于复杂的类,它执行简单的成员智能复制,因此对于复杂元素或动态分配的内存,您应该声明自己的。

§ 15.8.1 §15.8.1

If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly. 如果类定义未显式声明复制构造函数,则会隐式声明非显式构造函数。 If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; 如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数被定义为已删除; otherwise, it is defined as defaulted (11.4). 否则,它被定义为默认(11.4)。 The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor or assignment operator. 如果类具有用户声明的复制赋值运算符或用户声明的析构函数或赋值运算符,则不推荐使用后一种情况。

Why the copy happens 为什么要复制

Look at your class B c'tor: 看看你的class B c'tor:

class B {
public:
    explicit B(A aa) {}
};

You receive A by value , triggering a copy during the call. 您通过接收A,在通话期间触发副本。

If you would have change it to (notice A & aa ): 如果您将其更改为(注意A & aa ):

class B {
public:
    explicit B(A & aa) {}
};

There wouldn't be any copy... 没有任何副本......

Default copy constructor 默认复制构造函数

When you remove the c'tor, the compiler generates one for you when it can trivially do so: 当你删除c'tor时,编译器会为你生成一个,当它可以这么做时:

First, you should understand that if you do not declare a copy constructor, the compiler gives you one implicitly. 首先,你应该明白,如果你没有声明一个复制构造函数,编译器会隐式地给你一个。 The implicit copy constructor does a member-wise copy of the source object. 隐式复制构造函数执行源对象的成员方复制。

The default c'tor is equivalent to: 默认c'tor相当于:

MyClass::MyClass( const MyClass& other ) :
     x( other.x ), c( other.c ), s( other.s ) {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM