【问题标题】:Learning C++ from Java , trying to make a linked list从Java学习C++,尝试制作链表
【发布时间】:2011-02-09 01:57:08
【问题描述】:

我刚开始学习C++(来自Java)并且在做任何事情时都遇到了一些严重的问题:P 目前,我正在尝试制作一个链接列表,但一定是在做一些愚蠢的事情,因为我不断得到“ void 值没有被忽略,因为它应该是”编译错误(我已经将它标记在下面抛出它的位置)。如果有人可以帮助我解决我做错的事情,我将非常感激:)

另外,我不习惯在一般情况下选择通过引用、地址或值传递以及内存管理(目前我的所有节点和数据都声明在堆上)。 如果有人对我有任何一般性建议,我也不会抱怨:P

来自 LinkedListNode.cpp

的关键代码
LinkedListNode::LinkedListNode()
{
    //set next and prev to null
    pData=0; //data needs to be a pointer so we can set it to null for
             //for the tail and head.
    pNext=0;
    pPrev=0;
}

/*
 * Sets the 'next' pointer to the memory address of the inputed reference.
 */
void LinkedListNode::SetNext(LinkedListNode& _next)
{
    pNext=&_next;
}

/*
 * Sets the 'prev' pointer to the memory address of the inputed reference.
 */
void LinkedListNode::SetPrev(LinkedListNode& _prev)
{
    pPrev=&_prev;
}
//rest of class

来自 LinkedList.cpp 的关键代码

#include "LinkedList.h"

LinkedList::LinkedList()
{
    // Set head and tail of linked list.
    pHead = new LinkedListNode();
    pTail = new LinkedListNode();

     /*
      * THIS IS WHERE THE ERRORS ARE.
      */
    *pHead->SetNext(*pTail);
    *pTail->SetPrev(*pHead);
}
//rest of class

【问题讨论】:

  • 我强烈反对获取参考地址。相反,只需传递指针。这样调用者就知道您正在保存地址,并且不太可能传入局部变量。
  • @Ben:请耐心等待,我正试图弄清楚这一切。所以我假设你在谈论 SetNext 和 SetPrev 函数?最终用户不应该访问它们,他们应该只能访问,比如说,添加和删除方法,然后它们会调用它们。话虽如此,在这种情况下通过地址传递是否仍然更有意义?我原来的传递函数是,通过使用 const,我们将无法更改那里的数据,只能使用它(在这种情况下获取地址)。但是,我的思绪在想方设法理解这一切,所以欢迎提供帮助!
  • 是的,我说的正是 SetNext 和 SetPrev。我永远不会让通过引用传递的参数超过被调用函数的持续时间。调用者甚至可能不知道正在获取引用。对于私有函数,您所做的可能是“安全的”,但这不是好的做法,并且会损害可维护性。
  • 请拿起一本初学者的 C++ 书籍 (stackoverflow.com/questions/388242/…)。要正确学习 C++,请假装您从未学习过 Java。 C++ 与 Java 完全不同。

标签: java c++ pointers linked-list parameter-passing


【解决方案1】:

另外,我不习惯在一般情况下选择通过引用、地址或值传递以及内存管理(目前我的所有节点和数据都声明在堆上)。如果有人对我有任何一般性建议,我也不会抱怨:P

前 Java 程序员总是这样做。它是颠倒的。 您实际上应该从不堆分配数据。对象应该在堆栈上声明,如果他们需要堆分配的内存,他们应该在内部处理它,在它们的构造函数中分配它并在它们的析构函数中释放它。

这会导致代码更干净、更安全。

类成员也应该是值,而不是指针/引用,除非您特别需要在不同对象之间共享该成员。如果该类独占其成员,只需将其设为非指针值类型。这样它就在类本身内部进行分配,您不需要跟踪新/删除调用。

最简单的经验法则是不使用指针,除非你。您需要将对象分配到别处吗?为什么不能here分配,按值访问?即使对象必须从一个函数返回,或者作为参数传递给另一个函数,复制通常会解决这个问题。只需定义适当的复制构造函数和赋值运算符,并在必要时复制对象。

【讨论】:

    【解决方案2】:

    中领先的*
    *pHead->SetNext(*pTail);
    *pTail->SetPrev(*pHead);
    

    不需要。

    pHead 是一个指向节点的指针,您可以在其上调用 SetNext 方法作为 pHead->SetNext(..) 通过引用传递 object

    ->precedence 高于 *

    因此,您实际上是在尝试取消引用函数 SetNext 的返回值,该函数不返回任何内容,从而导致此错误。

    【讨论】:

    • 谢谢,工作就像一个魅力。也感谢您的解释,这更有意义。
    • 对。该错误来自尝试对来自pHead->SetNext(*pTail) 的返回值使用*(取消引用运算符)。成员访问和函数调用都优先于取消引用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    相关资源
    最近更新 更多