2015-09-03 46 views
3

我是新来的面向对象的编程,这可能是一个愚蠢的问题,但我不明白为什么使用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级使用

+0

http://stackoverflow.com/a/18611518/1012759它被标准禁止接受指针。 – CyberGuy

+3

@Cyber​​Guy这个问题说“复制对象”,而不是“创建复制构造函数”。您可以“复制对象”而无需复制构造函数。 – Yakk

+1

你确定A班比较好吗?这两个类看起来和我很相似,一个用无意义的拷贝构造函数,另一个用带指针的隐含构造函数。 – anatolyg

回答

4

A类是灵活,安全:您从任何一个对象的副本你,即使是暂时的。

B类不太安全,因为您可以使用nullptr调用构造函数。它的灵活性较低,因为只能使用ypur构造函数来复制可以获取地址的对象,而不是常量。

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 
+0

关于B的第一点是真的,第二点不是的(因为'B'有一个隐式定义的拷贝构造函数以及构造函数带一个指针,所以它仍然可以被复制) –

+0

@JonathanWakely当然!对不起,我可怜的措辞:我的意思是提供给B的构造函数,而不是真正的拷贝构造函数。我编辑过。 – Christophe

0

它是由标准禁止在复制构造使用指针:

C++标准草案n3376 - 部分12.8.2:

类X A非模板构造器是一个拷贝构造函数,如果它的第一个参数的类型为X &,const X &,volatile X &或const volatile X &,并且没有其他参数ETERS否则所有其他 参数都有默认参数

Why is the argument of the copy constructor a reference rather than a pointer?

+2

但是B的构造函数不是复制构造函数,所以没关系。 –

2

的事情是,如果一个构造函数被认为是由编译器拷贝构造函数,它是用特殊的方式使用。举例来说,如果你有一个函数,通过复制把你的A类型的参数,如:

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

然后调用该函数:

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

function收到的目标obj会由您提供的复制构造函数创建。所以,为您的类提供复制构造函数是件好事,这些复制构造函数将被复制,以便它们更好地适应语言功能和库。

在您的应用程序中创建类型的构造函数没有问题,如果这符合您的应用程序的需要,但编译器不会将其理解为复制构造函数,并且在编译器或库需要复制你的对象。

5

如果你没有为你的类声明一个拷贝构造函数,那么编译器无论如何都会为你声明一个。类必须有复制构造函数。它们被烘焙成语言并具有特殊的地位。没有它们,语言就无法运作。

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

所以,如果你想让你的类是可复制的,你应该在复制构造函数中定义复制逻辑。这很简单。

+0

“类**必须拥有复制构​​造函数。”不是真的。我不记得编译器不会为你发出拷贝构造函数的情况,但是从C++ 11开始,你可以显式地删除拷贝构造函数。 'std :: unique_ptr'没有拷贝构造函数。 – lvella

+1

@Ivella它仍然**有一个副本构造函数,这很重要。如果你试图复制一个'std :: unique_ptr',它将选择拷贝的拷贝构造函数,然后你会收到一个错误,因为它被删除了。 – Brian

+1

我认为“有”的定义在这里有点过于... – lvella

相关问题