C++ 带指针的复制构造函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/781760/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:15:56  来源:igfitidea点击:

Copy constructor with pointers

c++pointerscopy-constructor

提问by Biga

I have recently discovered that when I have pointers within a class, I need to specify a Copy constructor.

我最近发现当我在一个类中有指针时,我需要指定一个 Copy 构造函数。

To learn that, I have made the following simple code. It compiles, but gives me runtime error when performing the copy constructor.

为了了解这一点,我编写了以下简单代码。它编译,但在执行复制构造函数时给我运行时错误。

I am trying to copy just the value from the pointer of the copied object, but avoiding assigning the same address.

我试图只从复制对象的指针复制值,但避免分配相同的地址。

So, what's wrong here?

那么,这里有什么问题呢?

    class TRY{
        public:
        TRY();
    ~TRY();
        TRY(TRY const &);

        int *pointer;

        void setPointer(int);
    };


    void TRY::setPointer(int a){
        *pointer = a;

        return;
    }


    TRY::TRY(){}


    TRY::~TRY(){}


    TRY::TRY(TRY const & copyTRY){
        int a = *copyTRY.pointer;
        *pointer = a;
    }



    int main(){

        TRY a;
        a.setPointer(5);

        TRY b = a;

        b.setPointer(8);

        cout << "Address of object a = " << &a << endl;
        cout << "Address of object b = " << &b << endl;

        cout << "Address of a.pointer = " << a.pointer << endl;
        cout << "Address of b.pointer = " << b.pointer << endl;

        cout << "Value in a.pointer = " << *a.pointer << endl;
        cout << "Value in b.pointer = " << *b.pointer << endl;

        return 0;
    }

I'll be using this concept for other classes with lots of pointers in it, where I need to copy all values from on object to the other. Copying is initially necessary for this code, so I would like to keep the copying possibility (I won't be hiding the copy constructor as private).

我将把这个概念用于其他有很多指针的类,在那里我需要将所有值从一个对象复制到另一个对象。此代码最初需要复制,因此我想保留复制的可能性(我不会将复制构造函数隐藏为私有)。

Besides, the real class I need to implement has like 10 pointers, and it might be changing with time. Isn't there a somewhat smarter way to have a deep copy constructor in C++?...

此外,我需要实现的真正类有 10 个指针,并且可能会随着时间而改变。在 C++ 中没有更聪明的方法来拥有一个深拷贝构造函数吗?...

回答by Naveen

With the statement int* pointeryou have just defined a pointer but has not allocated any memory. First you should make it point to a proper memory location by allocating some memory like this: int* pointer = new int. Then in the copy constructor again you have to allocate the memory for the copied object. Also, don't forget to release the memory using delete in the destructor.

使用该语句,int* pointer您刚刚定义了一个指针,但尚未分配任何内存。首先,你应该使它指向正确的内存位置分配一些这样的记忆:int* pointer = new int。然后再次在复制构造函数中,您必须为复制的对象分配内存。另外,不要忘记在析构函数中使用 delete 释放内存。

I hope this example helps:

我希望这个例子有帮助:

class B
{

public:
    B();
    B(const B& b);
    ~B();
    void setVal(int val);

private:
    int* m_p;
};

B::B() 
{
    //Allocate the memory to hold an int
    m_p = new int;

    *m_p = 0;
}

B::B(const B& b)
{
    //Allocate the memory first
    m_p = new int;

    //Then copy the value from the passed object
    *m_p = *b.m_p;
}

B::~B()
{

    //Release the memory allocated
    delete m_p;
    m_p = NULL;
}

void B::setVal(int val)
{
    *m_p = val;
}

回答by aJ.

I have recently discovered that when I have pointers within a class, I need to specify a Copy constructor.

我最近发现当我在一个类中有指针时,我需要指定一个 Copy 构造函数。

It is not completely true. When you have pointers in your class and allocate the memory using newthen you have to worry about copy constructor. Also, don't forget the assignment operator and destructor. You have to delete the memory allocated using delete.

这并不完全正确。当您的类中有指针并使用分配内存时,new您必须担心复制构造函数。另外,不要忘记赋值运算符和析构函数。您必须删除使用分配的内存delete

It's called Law Of The Big Three.

这就是所谓的三巨头法则

Example:

例子:

  ~Matrix();  //Destructor
  Matrix(const Matrix& m); //Copy constructor
  Matrix& operator= (const Matrix& m); //Assignment operator

回答by unwind

If you want to do a deep copy, you of course must also allocate new memory to hold the values. If the original has a pointer to an int, and you don't want the copy to use the same pointer value, you must allocate new memory to hold an int, and then copy the value there.

如果要进行深度复制,当然还必须分配新内存来保存值。如果原始有一个指向 int 的指针,并且您不希望副本使用相同的指针值,则必须分配新内存来保存一个 int,然后将值复制到那里。

Your example is not very clear, it doesn't show the implementation of your copy constructor, or how the pointermember gets initialized.

你的例子不是很清楚,它没有显示你的复制构造函数的实现,或者pointer成员是如何初始化的。

回答by Nemanja Trifunovic

I have recently discovered that when I have pointers within a class, I need to specify a Copy constructor

我最近发现当我在一个类中有指针时,我需要指定一个复制构造函数

More often than not it is a good idea to simply disable it by declaring it (and the assigment operator) private and not implementing it.

通常情况下,通过将它(和赋值运算符)声明为私有而不实现它来简单地禁用它是一个好主意。

回答by Mykola Golubyev

if it has a pointer to a regular type then

如果它有一个指向常规类型的指针,那么

A::A(const A& a):
  pointer_( new int( *a.pointer_ ) )
{
}

if it has a pointer to some base class then

如果它有一个指向某个基类的指针,那么

A::A(const &a ):
  pointer_( a.pointer_->clone() )
{
}

Clone is a implementation of a prototype pattern

克隆是原型模式的实现

Don't forget to delete the pointer in the destructor

不要忘记删除析构函数中的指针

A::~A()
{
    delete pointer_;
}

To fix your example

修复你的例子

TRY::TRY(TRY const & copyTRY){
    int a = *copyTRY.pointer;
    pointer = new int(a);
}

回答by Ben Straub

Your problem is in this line right here:

您的问题就在这里:

    *pointer = a;

All the stuff that normally happens in your default constructor hasn't happened yet, including the allocation of memory for *pointer.

通常在默认构造函数中发生的所有事情都还没有发生,包括为*pointer.

The fix is to allocate memory for an integer. You can use mallocand friends or newfor this, but make sure it's the same method you use in your default constructor, because you only get one destructor, and the calls have to match.

解决方法是为整数分配内存。您可以使用mallocandfriends 或newfor this,但请确保它与您在默认构造函数中使用的方法相同,因为您只有一个析构函数,并且调用必须匹配。

回答by Zifre

If a member-wise (shallow) copy is okay, then you don't have to do anything. If you want a deep copy, you have to allocate new storage for copies of all the members.

如果成员明智的(浅层)副本没问题,那么您不必做任何事情。如果你想要一个深拷贝,你必须为所有成员的副本分配新的存储空间。

回答by Tom

When writing a Copy Constructor, you should allocate memory for all members. In your case:

编写复制构造函数时,应为所有成员分配内存。在你的情况下:

TRY::TRY(TRY const & copyTRY){
    pointer = new int(*(copyTry.pointer));
}

Operator= is somehow similar, but with no memory allocation.

Operator= 有点类似,但没有内存分配。

TRY& operator=(TRY const& otherTRY){
      this->a  = *(otherTry.pointer)
      return *this
}

回答by Tom

More often than not, if YOU need to write a copy constructor or assignment operator you're doing something wrong. Leave the copy constructors and assignment operators to the implementers of the standard library. Compose your classes of already-copyable and assignable elements and you won't have to write your own.

通常情况下,如果您需要编写复制构造函数或赋值运算符,那么您就做错了。将复制构造函数和赋值运算符留给标准库的实现者。组合已经可复制和可分配元素的类,您将不必编写自己的类。

For example, maybe that int * member should be a std::vector instead.

例如,也许 int * 成员应该是 std::vector 。

If you can't make the class default copyable/assignable, maybe you can make it non-copyable/assignable by declaring, but not implementing, a private copy constructor and assignment operator.

如果您不能使类默认为可复制/可分配,也许您可​​以通过声明但不实现私有复制构造函数和赋值运算符来使其不可复制/可分配。

Only if none of the above are feasible should you implement your own copy constructor or assignment operator.

只有当以上都不可行时,您才应该实现自己的复制构造函数或赋值运算符。