【问题标题】:Why am I getting a "void value not ignored as ought to be" error?为什么我会收到“不应忽略的无效值”错误?
【发布时间】:2014-01-22 06:55:22
【问题描述】:

首先,我想声明我正在处理一个家庭作业问题,因此,如果给出的任何答案不是简单的答案,而是,我将不胜感激解释。另外,如果您担心帮助解决家庭作业问题,我只想让您知道我的老师鼓励我们使用此网站寻求帮助,所以您不必觉得自己在帮助我作弊!

无论如何,这就是手头的问题。我正在制作一个基于控制台的小型“游戏”,您可以在其中尝试从起点Location 到终点LocationLocation 头文件如下所示:

enum Direction {NORTH, SOUTH, EAST, WEST};

class Location{
    string name;
    bool visited;
    Location* neighbors[4];

public:
    Location();
    Location(string locName);
    string getDescription();
    bool hasNeighbor(Direction dir);
    Location* getNeighbor(Direction dir);
    void setNeighbor(Direction dir,  Location* neighborLoc);
    string getName();
    void setName(string newName);
    bool visit();
    bool getVisited();
};

该程序的基本思想是每个Location 有四个其他可能的Location 可以链接到。 “游戏”的目标是让玩家从一个位置开始,在这种情况下,它是“一个深而黑的洞穴”,并通过遍历这些Locations 最终到达地表。

为了进行设置,我有一个函数void buildMap(Location* startLoc, Location* endLoc) 可以生成整个场景。我面临的问题是在这个功能期间出现的,我不明白问题是什么。对于 setNeighbor() 函数的每一行,我都收到错误“不应忽略的无效值”。我调查了这个错误,发现最常见的原因是当程序尝试使用函数时,好像它正在返回一个值,但我不知道我可以在哪里这样做。这是我的函数的一个示例:

void buildMap(Location* startLoc, Location* endLoc){

    //Initialize all of the locations on the heap with temporary pointers
    startLoc = new Location("a deep, dark cave");
    endLoc = new Location("the surface");
    Location* passage = new Location("a musty passage");
    Location* shaft = new Location("a twisting shaft");
    Location* alcove = new Location("a dusty alcove");
    Location* toSurface = new Location("a passage to the surface");
    Location* cavern = new Location("a collapsed cavern");
    Location* shore = new Location("the shores of an underground lake");

    //Set up the deep, dark, cave's neighbors
    *startLoc->setNeighbor(NORTH, passage);     //IDE changed my "." to a "->"? 
    *startLoc->setNeighbor(EAST, shore);       
    *startLoc->setNeighbor(SOUTH, cavern);

    //Set up the musty passage's neighbors
    *passage->setNeighbor(EAST, shaft);
    *passage->setNeighbor(SOUTH, startLoc);

    //Set up the twisting shaft's neighbors
    *shaft->setNeighbor(EAST, alcove);
    *shaft->setNeighbor(SOUTH, shore);

    //Set up the dusty alcove's neighbors
    *alcove->setNeighbor(SOUTH, toSurface);

    //Set up the passage to the surface's neighbors
    *toSurface->setNeighbor(NORTH, alcove);
    *toSurface->setNeighbor(WEST, endLoc);

    //Set up the collapsed cavern's neighbors
    *toSurface->setNeighbor(NORTH, startLoc);

    //Set up the shore's neighbors
    *toSurface->setNeighbor(NORTH, shaft);
    *toSurface->setNeighbor(WEST, startLoc);
}

如果有帮助,这里还有 setNeighbor 函数:

void Location::setNeighbor(Direction dir, Location* neighborLoc){
    neighbors[dir] = neighborLoc;
}

这是我收到的错误示例。它发生在具有相同错误的每个相似行上。

C:\Users\Zachary\Documents\School\CS162\Location\main.cpp:30: error: void value not ignored as it ought to be
             *startLoc->setNeighbor(NORTH, passage);  

非常感谢任何可以解决此错误的帮助,如果需要更多信息,请发表评论,以便我可以帮助您。

【问题讨论】:

  • 包括确切的错误消息以及导致它的行。
  • 提示: * 运算符对方法调用的结果进行操作。您可能会重新检查“一元*”和“->”的含义......
  • 变量前不加*怎么办?

标签: c++ oop pointers reference void


【解决方案1】:
*startLoc->setNeighbor(NORTH, passage);

该行正在尝试取消引用 void,这将不起作用。该行应为

startLoc->setNeighbor(NORTH, passage); // note the lack of *

所有setNeighbor 调用也是如此。

【讨论】:

  • 这似乎奏效了。你能解释这是为什么吗?我们今天刚刚讨论了取消引用指针等,所以它仍然有点混乱。我以为既然startLoc是指向Location的指针,我需要取消引用它来调整实际数据?
  • @zsherman 你做了,但是你做了两次——第一次是->操作符,第二次是前面的*,这实际上适用于result方法调用。阅读其他答案。
  • @zsherman 除了 Spook 所说的,(*ptr).somefunc() 取消引用一个指针并调用它的成员函数 somefuncptr->somefunc() 做同样的事情。
【解决方案2】:

错误似乎在这里:

*startLoc->setNeighbor(NORTH, passage);
...

您必须记住,a->b 表示 (*a).b。所以你的代码行实际上意味着(包括运算符优先级):

*((*startLoc).setNeighbor(NORTH, passage));

您正在取消引用 Location * 以获取 Location,然后调用一个返回 void 的方法,然后您尝试取消引用 void,这是被禁止的。

将这些行简单地更改为:

startLoc->setNeighbor(NORTH, passage);

这个版本也是可以接受的(虽然需要额外的括号):

(*startloc).setNeighbor(NORTH, passage);

【讨论】:

  • 他没有取消引用Location 对象,他取消了setNeighbor() 成员函数的“返回值”(无效)。
【解决方案3】:
*startLoc->setNeighbor(NORTH, passage);

startLoc 是一个指向Location 的指针,使用-> 访问setNeighbor 会返回void,你在解除对它的引用,这是非法的。我猜你的意思是 (*startLoc).setNeighbor(NORTH, passage); 这是有效的。问题源于对运营商.->的误解。

  • 如果变量中有structclass 对象,则可以通过. 运算符访问其成员,例如object.memberobject.member_func()

    李>
  • 但是,如果您有一个指向此类对象的指针,那么访问它的常用方法是object_ptr->memberobject_ptr->member_func()。这里-> 取消引用指向底层对象成员的指针。

  • 当您执行*object_ptr 时,您可以有效地取回对象本身,因此您可以像使用普通(非指针)变量(*object_ptr).member 一样访问它。

您正在做的是取消引用它两次,一次使用->,然后使用*。但是,编译器只采用第一个,它假定从函数返回的又是一个指针,并且您正试图通过 * 使用第二个取消引用来取消引用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    • 2011-10-08
    • 2010-11-15
    • 2017-01-16
    相关资源
    最近更新 更多