带指针的复制构造函数

发布于 2024-07-18 00:59:28 字数 1363 浏览 11 评论 0原文

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

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

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

那么,这里出了什么问题呢?

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

我将在其中包含大量指针的其他类中使用这个概念,在这些类中我需要将所有值从一个对象复制到另一个对象。 复制最初对于此代码是必要的,因此我想保留复制的可能性(我不会将复制构造函数隐藏为私有)。

此外,我需要实现的实际类有大约 10 个指针,并且可能会随着时间而变化。 在 C++ 中是否有一种更聪明的方法来拥有深度复制构造函数?...

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

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++?...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

呢古 2024-07-25 00:59:28

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

我希望这个例子有帮助:

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

With the statement int* pointer you 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.

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;
}
め可乐爱微笑 2024-07-25 00:59:28

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

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

这就是三巨头法则

例子:

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

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

It is not completely true. When you have pointers in your class and allocate the memory using new then 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.

It's called Law Of The Big Three.

Example:

  ~Matrix();  //Destructor
  Matrix(const Matrix& m); //Copy constructor
  Matrix& operator= (const Matrix& m); //Assignment operator
唐婉 2024-07-25 00:59:28

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

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

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.

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

迷爱 2024-07-25 00:59:28

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

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

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

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

Clone 就是 原型模式

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

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

来修复您的示例

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

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);
}
暗喜 2024-07-25 00:59:28

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

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

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.

人│生佛魔见 2024-07-25 00:59:28

您的问题就在这里:

    *pointer = a;

默认构造函数中通常发生的所有事情都还没有发生,包括为 *pointer 分配内存。

解决方法是为整数分配内存。 您可以为此使用 malloc 和朋友或 new ,但请确保它与您在默认构造函数中使用的方法相同,因为您只获得一个析构函数,并且调用具有匹配。

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.

The fix is to allocate memory for an integer. You can use malloc and friends or new for 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.

孤独患者 2024-07-25 00:59:28

如果成员明智的(浅)副本没问题,那么您无需执行任何操作。 如果您想要深复制,则必须为所有成员的副本分配新的存储空间。

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.

眼角的笑意。 2024-07-25 00:59:28

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

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

Operator= 在某种程度上类似,但没有内存分配。

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

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.

TRY& operator=(TRY const& otherTRY){
      this->a  = *(otherTry.pointer)
      return *this
}
我ぃ本無心為│何有愛 2024-07-25 00:59:28

这是复制构造函数的示例

class Test
{​​​​​​​
private:
    int *s;
    int size;
public:
    Test(int a, int b);
    Test(const Test&t);
    ~Test();
    void setValue(int l);
    void getValues();
}​​​​​​​;


Test::Test(int a, int b)
{​​​​​​​
    s = new int;
    *s = a;
    this->size = b;
}​​​​​​​
Test::Test(const Test&t) {​​​​​​​
    s = new int;
    *s = *(t.s);
    this->size = t.size;
}​​​​​​​
void Test::setValue(int l) {​​​​​​​
    *s = l;
}​​​​​​​
void Test::getValues() {​​​​​​​
    cout << "value of s: " << *s << endl;
    cout << "value of size: " << this->size << endl;
}​​​​​​​


Test::~Test() {​​​​​​​
    cout << "memory de allocated!!!" << endl;
    delete s;
}​​​​​​​

here is the example of a copy constructor

class Test
{​​​​​​​
private:
    int *s;
    int size;
public:
    Test(int a, int b);
    Test(const Test&t);
    ~Test();
    void setValue(int l);
    void getValues();
}​​​​​​​;


Test::Test(int a, int b)
{​​​​​​​
    s = new int;
    *s = a;
    this->size = b;
}​​​​​​​
Test::Test(const Test&t) {​​​​​​​
    s = new int;
    *s = *(t.s);
    this->size = t.size;
}​​​​​​​
void Test::setValue(int l) {​​​​​​​
    *s = l;
}​​​​​​​
void Test::getValues() {​​​​​​​
    cout << "value of s: " << *s << endl;
    cout << "value of size: " << this->size << endl;
}​​​​​​​


Test::~Test() {​​​​​​​
    cout << "memory de allocated!!!" << endl;
    delete s;
}​​​​​​​
镜花水月 2024-07-25 00:59:28

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

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

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

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

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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文