使用复制构造函数的好处是什么?

What are the benefits of using copy constructor?

本文关键字:是什么 复制 构造函数      更新时间:2023-10-16

我是面向对象编程的新手,这可能是一个愚蠢的问题,但我不明白为什么如果你想创建一个对象的副本,使用类a代码比使用类B代码更好。

class A {
    int num;
public:
    A(const A &ref) : num(ref.num) {};
};
class B { 
    int num;
public:
    B(B *ptToClass) : num(ptToClass->num) {};
};

如果我没记错的话,复制构造函数是在类a中使用的。

如果你不为你的类声明复制构造函数,编译器会为你声明一个。类必须具有复制构造函数。它们融入了语言,具有特殊的地位。没有它们,语言无法工作。

可能最好的例子是在按值传递时需要复制构造函数。当按值传递时,编译器将隐式调用复制构造函数。它不会调用构造函数B::B(B*)

所以,如果你希望你的类是可复制的,你应该在复制构造函数中定义复制逻辑。

类A是灵活和安全的:您可以从您拥有的任何A对象创建副本,即使它是临时的。

类B不太安全,因为可以用nullptr调用构造函数。它不太灵活,因为您只能使用ypur构造函数来复制可以从中获取地址的对象,并且该对象不是const。

B b1(...);        
const B b2(...); 
B fb();        // function returning a B
B b3(&b1);      
B b4(&b2);     // error b2 is const
B b5(&fb());   // error you can't take adress of a temporary 

问题是,如果一个构造函数被编译器认为是复制构造函数,那么它将以特殊的方式使用。例如,如果您有一个函数,它通过复制获取您的A类型的参数,如下所示:

void function(A obj) {
   // Do something with A
   // ...
}

然后调用这个函数:

int main() {
   A a_obj;
   function(a_obj);
}

function接收的对象obj将由您提供的复制构造函数创建。因此,为要复制的类提供复制构造函数是一件很好的事情,这样它们就能更好地适应语言的特性和库。

在你的class B中创建一个这样的构造函数是没有问题的,如果它适合你的应用程序的需要,但是它不会被编译器理解为复制构造函数,当编译器或库需要复制你的对象时,它不会被使用。

标准禁止在复制构造函数中使用指针:

c++标准草案n3376 -第12.8.2节:

类X的非模板构造函数是复制构造函数,如果其第一个形参类型为X&, const X&, volatile X&或者const volatileX&,或者没有其他参数,或者只有其他参数参数有默认实参

为什么复制构造函数的实参是引用而不是指针?

我认为一个更合适的问题是:何时提供用户定义的复制构造函数超过编译器提供的默认构造函数?

如我们所知,编译器提供了一个复制构造函数(默认的构造函数),用于按成员进行复制。

只要类是一个简单的具体类型(其行为在很大程度上类似于内置类型),这种按成员复制就不坏。但是对于复杂的具体类型或具有层次结构的类,按成员复制不是一个好主意,强烈建议程序员提供他自己的复制构造函数的实现(即提供用户定义的复制构造函数)。

作为一个经验法则,在类中提供用户定义的复制构造函数是个好主意。

相关文章: