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);
}

http://ideone.com/NltfUO