【问题标题】:How to implement my custom node class correctly based on my own object?如何根据我自己的对象正确实现我的自定义节点类?
【发布时间】:2019-07-13 18:26:41
【问题描述】:

我已经实现了一个名为 Customer 的类,这是头文件:它工作得很好。

现在,基于我的 Customer 类,我想实现一个 BST 树来存储客户信息,但我需要一个包含 Customer 对象、指向左孩子和右孩子的指针的节点类。我在正确实现 Node 类方面遇到了麻烦。特别是对于 Customer 对象。

class Customer {
public:
    Customer(string,char,int);
    string get_name();
    char get_initial();
    int get_account();
    void set_account(int);
    bool operator<(Customer & c);
    bool operator<=(Customer & c);
    bool operator>(Customer & c);
    bool operator>=(Customer & c);
    bool operator==(Customer & c);
    bool operator!=(Customer & c);

private:
    string name;
    char initial;
    int account;
    friend ostream& operator<<(ostream & os,  Customer & c);
};

#ifndef NODE_H_
#define NODE_H_

#include "Customer.h"

class Node {
public:
    Customer parent;
    Node* left;
    Node* right;
};

#endif /* NODE_H_ */

显示的错误:被隐式删除,因为默认定义格式错误:

【问题讨论】:

  • 如果不默认构造Customer,就无法构造Node。但是,没有办法默认构造 Customer。您只提供了Customer 构造的机制,它需要参数。无论如何,此处发布的代码(以及此发布的代码)不会产生此类错误。您选择 not 包含的代码(您正在创建 Node 对象的位置)是事情最终开始偏离轨道的地方。
  • 如果您阅读了整个错误消息,它应该会告诉您以上所有内容,您可能需要查看 IDE 的构建输出窗口

标签: c++ class


【解决方案1】:

这里的问题是关于Node 类的default constructor。默认构造函数,在class中自动生成,如果没有其他用户定义的构造函数。因此,默认构造函数尝试为类的所有成员生成默认值,并在尝试调用不存在的对象Customer 的默认构造函数时遇到问题(因为构造函数Customer(string,char,int); 存在,并且Customer 类没有用户定义的默认构造函数)。您可以使用多种解决方案(在这种特殊情况下,从最推荐到最不推荐排序。在其他情况下,此比率可能会有一些变化):


解决方案 1(推荐)

Node 类中定义一个构造函数,它使用Customer 类成员parent 的非默认构造函数:
class Node {
public:
    Node(string name, char c, int age) : parent(name, c, age) {}
    Customer parent;
    Node* left;
    Node* right;
};

解决方案 2

Customer类定义默认构造函数:

class Customer {
public:
    /*...*/
    Customer();
    /*...*/
}

为什么在这种情况下不是最推荐的方式?它解决了编译器的错误,代码比最推荐的方式少,那为什么不选择这种方式呢?这种方式有逻辑问题 - 空客户是什么意思?您如何知道Customer 对象何时为空?您可以在此处查看我的答案:C++ vector of struct allocated on stack 以了解如何识别在没有任何用户定义数据的情况下创建的对象。这些验证比强制用户提前设置一些数据要复杂一些。

但是 - 如果没有像我之前提到的那样的逻辑问题,或者不需要处理验证,或者验证值得在此解决方案中选择的情况下,这种方式可能是最好的方法。


解决方案 3(强烈不推荐)

Node 类中的parent 定义为指针(因此默认值为nullptr)。

为什么不选择这个选项?这个选项可能是让编译器错误消失的最简单和最快的方法——但是它会迫使你在你的程序中一直处理指针和内存管理的指针程序,并且会让你的生活比其他解决方案更难(在编译器错误消失后 - segfault (What is a segmentation fault?) 比编译器错误更烦人)。

【讨论】:

  • 另外值得补充的是,将解决方案 1 和解决方案 3 结合起来并没有错。解决方案 2 是一种反解决方案,绝对不推荐,但可能对新手很有吸引力,他们不喜欢它的问题会导致。
  • @john 我为每个解决方案添加了评分,以帮助需要此答案的人选择最佳方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
  • 2011-05-20
相关资源
最近更新 更多