简体   繁体   English

复制带有指向用户定义类型的指针的类的构造函数

[英]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);
}

http://ideone.com/NltfUO http://ideone.com/NltfUO

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM