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