面向对象编程风格和指向指针的指针 我想在C++中制作一个简单的链表类和其他数据结构来适应面向对象的编程。在编辑我的旧C代码之后,我得到了类似这样的东西(我刚刚包含了一个函数):

面向对象编程风格和指向指针的指针 我想在C++中制作一个简单的链表类和其他数据结构来适应面向对象的编程。在编辑我的旧C代码之后,我得到了类似这样的东西(我刚刚包含了一个函数):,c++,oop,linked-list,C++,Oop,Linked List,然而,这会产生难看的代码,并且容易发生内存泄漏。一定有更好的方法可以做到这一点,但我真的想不出什么。我试图为指针做一些方法,但在C++中是非法的。你们能教我如何正确的OOP风格处理像我这样的类吗?你们遇到的问题源于这样一个事实,即您的llist类实际上是链接列表中的一个节点,而不是整个列表,所以使用add方法是没有意义的。您会注意到,在非OOP代码中实际上也是如此,llistAdd函数不会作用于llist对象,而是作用于引用llist对象的对象(这里只是一个指针)。这就为您的问题提供了解决方案:

然而,这会产生难看的代码,并且容易发生内存泄漏。一定有更好的方法可以做到这一点,但我真的想不出什么。我试图为指针做一些方法,但在C++中是非法的。你们能教我如何正确的OOP风格处理像我这样的类吗?

你们遇到的问题源于这样一个事实,即您的
llist
类实际上是链接列表中的一个节点,而不是整个列表,所以使用
add
方法是没有意义的。您会注意到,在非OOP代码中实际上也是如此,
llistAdd
函数不会作用于
llist
对象,而是作用于引用
llist
对象的对象(这里只是一个指针)。这就为您的问题提供了解决方案:将旧类重命名为
llistnode
,并创建一个新的
llist
类,该类的指针指向列表的开头
llistnode
,并在此新类上实现

template<typename T> class llistnode
{
  public:
    T data;
    llistnode<T>* next;

    llistnode() {next=nullptr;}
    llistnode(const T& d) {data=d;next=nullptr;}
};

template<typename T> class llist
{
  private:
    llistnode<T>* head;

  public:
    void Add(const T& d) {
        llistnode<T>* new_node = new llistnode<T>(d);
        new_node.next = head;
        head = new_node;
    }
};
模板类llistnode
{
公众:
T数据;
下一步;
llistnode(){next=nullptr;}
llistnode(const T&d){data=d;next=nullptr;}
};
模板类llist
{
私人:
利斯特诺*头;
公众:
无效添加(常量T&d){
llistnode*新节点=新的llistnode(d);
new_node.next=头部;
head=新的_节点;
}
};

为什么不使用
std::list
std::vector
让stdlib来完成这项艰巨的工作呢?这是熟悉面向对象编程和研究数据结构的结合。我必须知道引擎盖下面发生了什么:P@MadPidgeon:列表不够复杂,无法适应OOP。不需要继承、使用虚拟函数等等。试试更复杂的东西。也许是电脑游戏吧。另一方面,你们似乎不知道,所以你们应该读一下。我不理解你们的代码。哪一个是llistnode,您将
T数据保存在哪里?哇!我在
llist
中使用了错误的节点类型-希望它现在有意义。非常感谢您的回答。我真该看看这个。不过我有一个小问题:假设我想遍历列表并在列表中插入节点。我该怎么做?在这段代码中,我只能在开头添加节点。或者至少,我没有遗漏什么吗?请记住,对于链接列表,为了在前面(或后面,如果列表是双链接的)以外的位置插入新元素,您需要在要插入的位置之前直接引用节点。因此,将
insertAfter
方法添加到执行此操作的节点类中是有意义的。
int main()
{
    llist<int>* my_integer_list = nullptr;

    llistAdd(&my_integer_list,42);
    llistAdd(&my_integer_list,128);
    llistAdd(&my_integer_list,1337);

    for(auto itr = &my_integer_list; (*itr) != nullptr; llistItrAdv(&itr))
        cout<<(**itr).data<<endl;

    llistClear(&my_integer_list);

    return 0;
}
template<typename T> llist<T>* llist<T>::Add(const T& d)
{
    llist<T> *temp = new llist<T>(d);
    temp->next = this;
    return temp;
}

int main()
{
    llist<int>* my_integer_list = nullptr;

    my_integer_list = my_integer_list->Add(42);

    my_integer_list = my_integer_list->Clear();

    return 0;
}
template<typename T> class llistnode
{
  public:
    T data;
    llistnode<T>* next;

    llistnode() {next=nullptr;}
    llistnode(const T& d) {data=d;next=nullptr;}
};

template<typename T> class llist
{
  private:
    llistnode<T>* head;

  public:
    void Add(const T& d) {
        llistnode<T>* new_node = new llistnode<T>(d);
        new_node.next = head;
        head = new_node;
    }
};