C ++复制构造函数+指针对象 [英] C++ Copy Constructor + Pointer Object

查看:254
本文介绍了C ++复制构造函数+指针对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在C ++学习大三。我设法做大三非常简单的程序..但我不知道如何使用对象指针。以下是我的第一尝试。

I'm trying to learn "big three" in C++.. I managed to do very simple program for "big three".. but I'm not sure how to use the object pointer.. The following is my first attempt.

我在写这篇文章时有疑问...

I have a doubt when I was writing this...

问题


  1. 这是实现默认构造函数的正确方法吗?我不知道我是否需要它。但是我在另一个线程中发现了有指针的拷贝构造函数,我需要在拷贝构造函数中复制地址之前为该指针分配空间。

  2. 如何分配指针变量复制构造函数?我在Copy Constructor中写的方式可能是错误的。

  3. 我需要为复制构造函数和operatior =?实现相同的代码(除了return)。

  4. 我需要删除指针在析构函数?
  1. Is this the correct way to implement the default constructor? I'm not sure whether I need to have it or not. But what I found in another thread about copy constructor with pointer is that I need to allocate the space for that pointer before copying the address in copy constructor..
  2. How to assign the pointer variable in the copy constructor? The way that I wrote in Copy Constructor might be wrong.
  3. Do I need to implement the same code (except return ) for both copy constructor and operatior=?
  4. Am I correct in saying that I need to delete the pointer in destructor?

class TreeNode
{
public:  
   TreeNode(); 
   TreeNode(const TreeNode& node);
   TreeNode& operator= (const TreeNode& node);
   ~TreeNode();
private:
   string data;
   TreeNode* left;
   TreeNode* right;
   friend class MyAnotherClass;
};


/ p>

Implementation

TreeNode::TreeNode(){

    data = "";  

}

TreeNode::TreeNode(const TreeNode& node){
     data = node.data;

     left = new TreeNode();
     right = new TreeNode();

     left = node.left; 
     right = node.right;
}

TreeNode& TreeNode::operator= (const TreeNode& node){
     data = node.data;
     left = node.left;
     right = node.right;
     return *this;
}

TreeNode::~TreeNode(){
     delete left;
     delete right;
}

提前感谢。

推荐答案


我是否需要删除析构函数中的指针?

Am I correct in saying that I need to delete the pointer in destructor?

每当设计这样的对象时,你首先需要回答这个问题:对象是否拥有指针指向的内存?如果是,那么显然对象的析构函数需要清理内存,所以是的,需要调用delete。这似乎是你的意图与给定的代码。

Whenever designing an object like this, you first need to answer the question: Does the object own the memory pointed to by that pointer? If yes, then obviously the object's destructor needs to clean up that memory, so yes it needs to call delete. And this seems to be your intent with the given code.

然而在某些情况下,你可能希望有指向其他对象的指针,通过别的东西。在这种情况下,您不想调用删除,因为程序的其他部分有责任这样做。此外,这改变了进入拷贝构造函数和赋值运算符的所有后续设计。

However in some cases, you might want to have pointers that refer to other objects whose lifetime is supposed to be managed by something else. In that case you don't want to call delete because it is the duty of some other part of the program to do so. Furthermore, that changes all the subsequent design that goes into the copy constructor and assignment operator.

我将继续回答其余的问题,假设你

I'll proceed with answering the rest of the questions under the assumption that you do want each TreeNode object to have ownership of the left and right objects.


这是否是实现默认构造函数的正确方法?

Is this the correct way to implement the default constructor?

否。你需要初始化 left right 指针为NULL(如果你喜欢,则为0)。这是必要的,因为未指定的指针可以具有任何任意值。如果你的代码默认构造一个TreeNode,然后销毁它而不给这些指针任何东西,那么删除将调用任何初始值。所以在这个设计中,如果这些指针没有指向任何东西,那么你必须保证它们被设置为NULL。

No. You need to initialize the left and right pointers to NULL (or 0 if you prefer). This is necessary because unintialized pointers could have any arbitrary value. If your code ever default constructs a TreeNode and then destroys it without ever assigning anything to those pointers, then delete would be called on whatever that initial value is. So in this design, if those pointers aren't pointing at anything, then you must guarantee that they are set to NULL.


在复制构造函数中分配指针变量?我在Copy Constructor中写的方式可能是错误的。

How to assign the pointer variable in the copy constructor? The way that I wrote in Copy Constructor might be wrong.

left = new TreeNode(); 创建一个新的TreeNode对象并设置 left 以指向它。 left = node.left; 重新分配指针指向任何TreeNode对象 node.left 指向。这有两个问题。

The line left = new TreeNode(); creates a new TreeNode object and sets left to point to it. The line left = node.left; reassigns that pointer to point to whatever TreeNode object node.left points to. There are two problems with that.

问题1:没有什么现在指向那个新的TreeNode。

Problem 1: Nothing now points to that new TreeNode. It is lost and becomes a memory leak because nothing can ever destroy it.

问题2:现在剩下 node.left 最终指向同一个TreeNode。这意味着被拷贝构造的对象和它从中取值的对象都将认为它们拥有相同的TreeNode,并且在它们的析构函数中都调用delete。

Problem 2: Now both left and node.left end up pointing to the same TreeNode. That means the object being copy constructed and the object it's taking values from will both think they own that same TreeNode and will both call delete on it in their destructors. Calling delete twice on the same object is always a bug and will cause problems (including possibly crashes or memory corruption).

由于每个TreeNode拥有它的左,右节点,因此,可能最合理的事情是做副本。所以你会写类似的:

Since each TreeNode owns its left and right nodes, then probably the most reasonable thing to do is make copies. So you would write something similar to:

TreeNode::TreeNode(const TreeNode& node)
    : left(NULL), right(NULL)
{
    data = node.data;

    if(node.left)
        left = new TreeNode(*node.left);
    if(node.right)
        right = new TreeNode(*node.right);
}




我需要实现相同的代码复制构造函数和operatior =?

Do I need to implement the same code (except return ) for both copy constructor and operatior=?

几乎肯定。或者至少,每个中的代码应该具有相同的最终结果。如果拷贝构造和赋值有不同的效果,这将是非常混乱。

编辑 - 上面的段落应该是:导致从另一个对象复制数据。这通常涉及非常类似的代码。但是,赋值运算符可能需要检查是否有任何已分配给 left right 。因此,它也可能需要注意自我分配,或者以不会在自我分配过程中造成任何不良后果的方式写入。

EDIT - The above paragraph should be: The code in each should have the same end result in that the data is copied from the other object. This will often involve very similar code. However, the assignment operator probably needs to check if anything has already been assigned to left and right and so clean those up. As a consequence, it may also need to watch out for self-assignment or else be written in a way that doesn't cause anything bad to happen during self-assignment.

事实上,有一些方法来实现一个使用另一个,所以操作成员变量的实际代码只写在一个地方。 SO的其他问题已经讨论过,例如这一个

In fact, there are ways to implement one using the other so that the actual code that manipulates the member variables is only written in one place. Other questions on SO have discussed that, such as this one.

这篇关于C ++复制构造函数+指针对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆