class 的复制构造函数,带有指向用户定义类型的指针
copy constructor for a class with pointer to a user defined type
我见过许多 classes 的复制构造函数示例,其中成员变量作为指向 int 或 char 的指针。有人可以建议使用成员 ptrB 为 class A 编写复制构造函数的正确方法吗,它是指向用户定义的 class B 的指针。
这是否正确:
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);
}
如果 ptrB 是这样定义的:
shared_ptr<B> ptrB;
然后这个?
A::A(const A& other)
{
ptrB(new B);
*(ptrB) = *(other.ptrB);
}
谢谢。
好的,如评论所述,这里是答案:
在裸指针的情况下,我上面的代码可以工作,但这是一个更好的版本,因为它使用了初始化列表并且性能更好:
A::A(const A& other):ptrB(new B(other.ptrB)) {}
并且在 shared_ptr 的情况下,我不需要复制构造函数和析构函数。
因为你用 "deep-copy" 标记了 post 我假设你希望复制构造函数这样做。使用 shared_ptr 生成的默认复制构造函数执行 而不是 深复制。
我建议复制类指针成员有两种通用形式。
Deep(const Deep& other): ptr(new T(*other.ptr)) {}
和
Shallow(const Shallow& other) = default;
请注意,像这样的浅拷贝不适用于 unique_ptr。通过设计,unique_ptr 可以防止这种情况发生。
这是每个示例,显示了差异。注意,在实践中使用原始版本很容易导致内存泄漏。重要的一点是浅拷贝之后,修改副本就是修改原件。
#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);
}
我见过许多 classes 的复制构造函数示例,其中成员变量作为指向 int 或 char 的指针。有人可以建议使用成员 ptrB 为 class A 编写复制构造函数的正确方法吗,它是指向用户定义的 class B 的指针。
这是否正确:
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);
}
如果 ptrB 是这样定义的:
shared_ptr<B> ptrB;
然后这个?
A::A(const A& other)
{
ptrB(new B);
*(ptrB) = *(other.ptrB);
}
谢谢。
好的,如评论所述,这里是答案:
在裸指针的情况下,我上面的代码可以工作,但这是一个更好的版本,因为它使用了初始化列表并且性能更好:
A::A(const A& other):ptrB(new B(other.ptrB)) {}
并且在 shared_ptr 的情况下,我不需要复制构造函数和析构函数。
因为你用 "deep-copy" 标记了 post 我假设你希望复制构造函数这样做。使用 shared_ptr 生成的默认复制构造函数执行 而不是 深复制。
我建议复制类指针成员有两种通用形式。
Deep(const Deep& other): ptr(new T(*other.ptr)) {}
和
Shallow(const Shallow& other) = default;
请注意,像这样的浅拷贝不适用于 unique_ptr。通过设计,unique_ptr 可以防止这种情况发生。
这是每个示例,显示了差异。注意,在实践中使用原始版本很容易导致内存泄漏。重要的一点是浅拷贝之后,修改副本就是修改原件。
#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);
}