【发布时间】:2021-11-22 16:13:40
【问题描述】:
假设我已经定义了一些类B 和C。
现在,让我们考虑以下类:
class A{
public:
int att1;
int att2;
std::shared_ptr<B> b_ptr;
std::shared_ptr<C> c_ptr;
A(const A& a);
};
现在,问题是如何实现复制构造函数。
目前在代码中,这就是正在做的事情:
A::A(const A& a){
att1 = a.att1;
att2 = a.att2;
b_ptr = a.b_ptr;
c_ptr = a.c_ptr;
}
最后两行将调用std::shared_ptr的复制构造函数,并将底层指针的所有者数加1。
但是,让一个复制构造函数来做这件事不是一个坏主意吗?这意味着在调用复制构造函数的任何地方,它实际上都会与初始对象有关系,因为B 和C 类的对象实际上并没有被复制,而只有指针被复制。
我意识到,由于使用了shared_ptr,至少这不会造成任何内存泄漏。
这是一种常见的做法吗?有任何正当理由这样做吗?还是我应该一起避免?
【问题讨论】:
-
shared_ptr用于共享所有权。所以是的,你是打算像那样使用它们。如果是错的,为什么类的开头是shared_ptr? -
它是否“坏”是您必须做出的决定。深复制和浅复制都有自己的位置,由您决定
A的性质决定了一个副本是应该只复制指针还是同时复制指向的对象。 -
Nit:你应该使用成员初始化列表
A::A(...) : att1(a.att1), ... { }而不是赋值。注意b_ptr = a.b_ptr不调用副本constructor,而是调用副本assignment。 (要调用复制构造函数,您需要使用初始化列表......这就是您应该使用它的原因。) -
Re:“如何实现复制构造函数”:在这种情况下,没有什么需要做的。问题中的代码与编译器生成的复制构造函数完全相同,但效率稍低(因为它不使用成员初始值设定项列表)。所以把它放在一边。编译器会帮你做的。
标签: c++ pointers smart-pointers