【问题标题】:Pointer members of a class during assignment operator overloading赋值运算符重载期间类的指针成员
【发布时间】:2014-05-18 02:11:46
【问题描述】:

我正在尝试用 C++ 编写树构造程序。 (它是 McCreight 的后缀树)但我对节点的赋值运算符重载有问题,特别是我的类节点中的指针属性! 我的树构造方法中有这段代码不起作用(解释如下):

void ST::insert(int suffix, Node& leaf)
{
    .
    .
    .
    leaf=find_path(u.suffix);
    cout<<leaf.id<<" "<<leaf.parent->id<<'\n';
    .
    .
    .
}

Node ST::find_path(Node* node, int suffix)
{
    .
    .
    .
    cout<<leaf.parent->id<<'\n';
    return leaf;
}

find_path 中的 cout 打印正确的父 ID,但是当将节点返回到 insert() 时,它的父节点丢失了。插入中的 cout 打印正确的“叶子 id”,但它不知道“叶子的父 id”。

我的 Node 类代码是这样的:

class Node
{
public:
    int id;
    Node* parent;
    vector <Node> children;
    vector <int> startPointer;
    Node* SL;
    int strDepth;
    Node()
    {
        parent=NULL;
        SL=NULL;
    }

Node& operator=(const Node node2)
{
    this->id=node2.id;
    if(this != &node2 && node2.parent!=NULL && node2.SL!=NULL)
    {
        *parent = *(node2.parent);
        parent = (node2.parent);
        *SL=*(node2.SL);
    }
    this->children=node2.children;
    this->startPointer=node2.startPointer;
    this->strDepth=node2.strDepth;
}

我尝试了很多方法来更改这个重载的运算符,但每种方法都会给出一些其他错误(通常是运行时,如 NullPointerException),我在此处包含的代码是迄今为止给出最佳答案的代码,但除非我找到一种方法知道返回节点的父节点我无法完成这个!当然,我可以将父母和祖父母作为单独的节点返回,但这并不有趣。非常感谢任何帮助。谢谢!

【问题讨论】:

  • 您的代码有很多问题:首先,赋值运算符(除非您正在执行它执行诸如复制和交换习惯用法之类的操作)必须通过 const 引用获取其参数,而不是通过值。第二:你已经打破了三法则:你应该实现一个自定义复制ctor、一个(正确的)赋值运算符和一个析构函数。
  • 谢谢!但是你介意说如果我不打算在我的代码中使用那个ctor,为什么需要复制ctor?重载 = 运算符不会做同样的事情吗? (我有析构函数,但我没有在这里复制所有代码!)我复制这个构造函数只是为了表明每个节点的父指针都由 NULL 初始化,所以它不会导致错误!谢谢。

标签: c++ pointers tree operator-overloading assignment-operator


【解决方案1】:

使用std::shared_pointer作为指向节点的链接,使用std::weak_pointer作为反向链接。

您可以为您的类专门化 shared_pointer,以便添加的簿记数据存储在节点本身中。看enable_shared_from_this&lt;T&gt;

【讨论】:

  • 这很聪明,很有帮助!太感谢了!我已经改变了我的指针,现在尝试调试!我根本不知道共享和弱ptrs。
【解决方案2】:

您的赋值运算符未正确实现。试试这个:

Node& operator=(const Node &node2)
{
    if(this != &node2)
    {
        this->id=node2.id;
        this->parent = node2.parent;
        SL=node2.SL;
        this->children=node2.children;
        this->startPointer=node2.startPointer;
        this->strDepth=node2.strDepth;
    }
    return *this;
}

在这种情况下,您可以完全省略该运算符,让编译器为您自动生成一个默认运算符,因为它会生成相同的代码。

【讨论】:

  • 谢谢。我(再次)尝试了这个,但是 find_path() 中的 cout 给出了 8 作为父 ID,而 insert() 中的 cout 给出了 5696520!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-03
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 2012-02-11
相关资源
最近更新 更多