我是面向对象编程的新手,这可能是一个愚蠢的问题,但我不明白为什么如果要创建一个对象的副本,使用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 :(得分:5)
如果您没有为您的类声明复制构造函数,编译器无论如何都会为您声明一个。类必须具有复制构造函数。他们已经融入语言并具有特殊地位。没有它们,语言就无法运作。
可能最好的例子是在传递值时需要复制构造函数。当您按值传递时,编译器将隐式调用复制构造函数。它不会调用构造函数B::B(B*)
。
因此,如果您希望您的类可以复制,则应在复制构造函数中定义复制逻辑。它更容易。
答案 1 :(得分:4)
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
答案 2 :(得分:2)
问题在于,如果编译器将构造函数视为复制构造函数,则以特殊方式使用它。例如,如果您有一个函数可以通过副本获取类型A
的参数,如下所示:
void function(A obj) {
// Do something with A
// ...
}
然后你调用那个函数:
int main() {
A a_obj;
function(a_obj);
}
obj
收到的对象function
将由您提供的复制构造函数创建。因此,为要复制的类提供复制构造函数是一件好事,这样它们就能更好地适应语言特性和库。
在class B
中创建类型的构造函数没有问题,如果这符合您的应用程序需求,但编译器不会将其理解为复制构造函数,并且不会在编译器或库需要复制对象时使用。
答案 3 :(得分:0)
标准禁止在复制构造函数中使用指针:
C ++草案标准n3376 - 第12.8.2节:
类X的非模板构造函数是复制构造函数(如果是) 第一个参数是X&类型,const X&,volatile X&或const volatile X&,并且没有其他参数或其他所有参数 参数有默认参数
Why is the argument of the copy constructor a reference rather than a pointer?