[英]copy constructor for a class with pointer to a user defined type
I have seen many examples of copy constructor for classes with member variables as pointer to int or char. 我已经看到许多类的复制构造函数示例,其中成员变量作为指向int或char的指针。 Can someone advise on the right way of writing a copy constructor for a class A with a member ptrB which is a pointer to user defined class B please. 有人可以建议使用成员ptrB为类A编写复制构造函数的正确方法,该成员是指向用户定义的类B的指针。
Is this correct: 这个对吗:
class A {
private:
B *ptrB;
public:
A() { ptrB = new B; }
A(const A& other);
~A();
}
A::A(const A& other)
{
ptrB = new B;
*(ptrB) = *(other.ptrB);
}
and If ptrB was defined like this: 如果ptrB定义如下:
shared_ptr<B> ptrB;
then this? 那么这个?
A::A(const A& other)
{
ptrB(new B);
*(ptrB) = *(other.ptrB);
}
Thanks. 谢谢。
Since you tagged the post with "deep-copy" I assume you want the copy constructor to do that. 由于您使用“深层复制”标记了帖子,我假设您希望复制构造函数执行此操作。 The default copy constructor generated using shared_ptr does not deep copy. 使用shared_ptr生成的默认复制构造函数不会进行深层复制。
I would suggest that there are two general forms for copying a pointer-like member. 我建议复制指针式成员有两种通用形式。
Deep(const Deep& other): ptr(new T(*other.ptr)) {}
and 和
Shallow(const Shallow& other) = default;
Note, a shallow copy like that won't work for a unique_ptr. 请注意,像这样的浅拷贝不适用于unique_ptr。 By design, unique_ptr prevents that. 通过设计,unique_ptr可以防止这种情况发生。
Here is an example of each, showing the difference. 以下是每个示例,显示差异。 Nb, using the raw version in practice could easily lead to a memory leak. Nb,在实践中使用原始版本很容易导致内存泄漏。 The important point is that after the shallow copy, modifying the copy modifies the original. 重要的是,在浅拷贝之后,修改拷贝会修改原始拷贝。
#include <memory>
#include <iostream>
template<typename T, typename TPtr>
struct Deep
{
TPtr ptr;
Deep() : ptr(new T) {}
T get() const { return *ptr; }
void set(T t) { *ptr = t; }
Deep(const Deep& other): ptr(new T(*other.ptr)) {}
};
template<typename T, typename TPtr>
struct Shallow
{
TPtr ptr;
Shallow() : ptr(new T) {}
T get() const { return *ptr; }
void set(T t) { *ptr = t; }
Shallow(const Shallow& other) = default;
};
template<typename T>
using raw_ptr = T*;
template<typename T>
void test(const T& a1)
{
auto a2 = a1;
a2.set(a2.get() + 1);
std::cout << a1.get() << " " << a2.get() << std::endl;
}
using std::shared_ptr;
int main()
{
Deep<int, raw_ptr<int> > rawDeep;
rawDeep.set(1);
test(rawDeep);
Deep<int, shared_ptr<int> > sharedDeep;
sharedDeep.set(1);
test(sharedDeep);
Shallow<int, raw_ptr<int> > rawShallow;
rawShallow.set(1);
test(rawShallow);
Shallow<int, shared_ptr<int> > sharedShallow;
sharedShallow.set(1);
test(sharedShallow);
}
Ok as in the comments, here is the answer: 好的,如评论中所示,答案如下:
in the case of naked pointer my code above works but this is a better version as uses initialization list and performs better: 在裸指针的情况下我的代码可以工作,但这是一个更好的版本,因为使用初始化列表并执行得更好:
A::A(const A& other):ptrB(new B(other.ptrB)) {}
and in the case of shared_ptr, I don't need copy constructor and destructor. 在shared_ptr的情况下,我不需要复制构造函数和析构函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.