【问题标题】:Double linked list in Data Structures and Algorithms in c++C ++中数据结构和算法中的双链表
【发布时间】:2021-09-16 14:23:02
【问题描述】:

所以我在 c 和 c++ 中的数据结构和算法中看到了这个代码片段:

class DLinkedList { // doubly linked list
public:
    DLinkedList(); // constructor
    ~DLinkedList(); // destructor
    bool empty() const; // is list empty?
    const Elem& front() const; // get front element
    const Elem& back() const; // get back element
    void addFront(const Elem& e); // add to front of list
    void addBack(const Elem& e); // add to back of list
    void removeFront(); // remove from front
    void removeBack(); // remove from back
private: // local type definitions
    DNode* header; // list sentinels
    DNode* trailer;
protected: // local utilities
    void add(DNode* v, const Elem& e); // insert new node before v
    void remove(DNode* v); // remove node v
};

我的问题是:为什么成员函数 add()remove() protected (以及何时应该使用关键字 protected

编辑:DNode 在这里定义:

typedef string Elem; // list element type
class DNode { // doubly linked list node
private:
    Elem elem; // node element value
    DNode* prev; // previous node in list
    DNode* next; // next node in list
    friend class DLinkedList; // allow DLinkedList access
};

【问题讨论】:

  • 也许作者想在后面的章节中使用继承。受保护的成员可以被派生的孩子使用。根据en.cppreference.com/w/cpp/language/access:“受保护的继承:在访问说明符之后列出的基类的公共和受保护成员是派生类的受保护成员,而派生类无法访问基类的私有成员”
  • 它们是辅助函数(不打算成为 API 的一部分;你可以知道,因为它们处理节点指针),但为什么它们受到保护而不是私有是一个只有作者的谜可以帮到你。
  • 我们喜欢 cmets,不是吗?
  • 关于什么属于公共 API 和什么受保护的决定可能是一个主观的设计决定。您是在让我们猜测作者的设计,并且没有太多信息可以继续。我最好的猜测是答案在于DNode(这些受保护成员使用)和Elem(一些公共成员使用)的定义。是否可以提供更多上下文而不会陷入压倒性的代码转储?

标签: c++ linked-list doubly-linked-list


【解决方案1】:

当您希望 API 查看某些方法但确实希望从类及其子类(包外部或包内)访问该方法时,您使用 protected ) 和同一个包中的类

add() 和 remove() 受到保护的原因是为了提供数据抽象并防止未经授权的人员使用这些函数

【讨论】:

  • 我明白你的意思,这可能是一个不好的问题,因为我本质上是在让你猜测作者在写这本书时的想法,但为什么不应该 add() 和 @987654322 @公众可以访问吗?
  • 就像你说的我猜到了,但我的猜测是基于软件的正常工作方式,并非所有最终用户都可以访问所有功能。
  • 例如,一家公司使用优先级队列来管理任务。员工无权添加(入队)只有某些成员才能执行的任务,但他们有权将任务标记为已完成或将其出队 - 这是一个非常松散的示例,因为还有更多复杂性
【解决方案2】:

SO protected 意味着它只能由派生类(在这种情况下从类 Dlinkedlist 继承的类)或此类的朋友(请参阅声明类的朋友)使用。但是,很难说出作者声明它们受保护的意思

【讨论】:

    【解决方案3】:

    只有当这个类被用作继承的基类时,受保护的才有意义。受保护的方法只能从类或派生类中的方法访问。

    我希望您会发现作者继续定义派生自 DLinkedList 的其他示例数据结构。

    【讨论】:

    • 旁注:如果打算将来继承,您应该考虑使析构函数virtual 允许运行时多态性。