C ++ make error:object_var尚未声明

时间:2015-04-07 22:15:12

标签: c++ object types

  
      
  • 您可能忘记在使用ProblemClass的文件中包含problemclass.h。
  •   
  • 你可能在自己的头文件或你正在使用它的地方错误拼写了ProblemClass的名称。这可以是
      很难发现是否是写作等大写错误   Problemclass或problemClass而不是ProblemClass。
  •   
  • 您可以将包含警卫#defines从一个头文件复制粘贴到另一个头文件,然后忘记更改已定义的名称。   然后只有这两个头文件中的第一个将采取   效果。
  •   
  • 您可以将ProblemClass放在命名空间A中,在这种情况下,如果您引用的话,必须将ProblemClass引用为A :: ProblemClass   从名称空间A。
  • 之外的它   
  • 您可能正在使用模板而不期望两阶段查找以它的方式工作。
  •   
  • 您可能拼错了包含中的文件名。如果您还有旧版本,编译器也不会报告错误   错误名称下该文件的版本。
  •   
  • 你可以让ProblemClass成为一个只在你包含problemclass.h之后才被定义的宏,在这种情况下你看到的是什么   ProblemClass被宏的其他东西取代   预处理器。
  •   
  • 您可以在除problemclass.h之外的头文件中定义ProblemClass,然后problemclass.h实际定义了一些东西   别的。
  •   

以上是从另一个类似的问题中得到的,我发现这些要点很有用,但没有一个真正解决了我的问题,如下所述:

我正在为机器人创建一个自然语言处理器,为软件提供各种对象来表示其环境中的真实世界项目(暂时阻止世界),Block中定义的对象之一:

    /*
 * Block.h
 *
 *  Created on: 11 Mar 2015
 *      Author: Edward
 */

#ifndef BLOCK_HPP_
#define BLOCK_HPP_

#include "typedefinitions.h"
#include "dynamixel.h"
#include "BasicRobotFunctions.hpp"

class Block {
public:
    bool grounded;
    //TODO position is a deprecated variable, replace with distance from
    //pos position;
    int number;
    int distance;
    int object_brightness;
    Block(BasicRobotFunctions basic);
    virtual ~Block();
    void setBrightness(int brightness);
    void setGrounded(bool ground);
    //void setPosition(int x, int y);
    void setDistance(int number);
    void setNumber(int number);
    //pos getPosition();
    int getNumber();
    int getDistance();
    bool getGrounded();
    int getBrightness();
    int lookAround(BasicRobotFunctions basic);
};

#endif /* BLOCK_H_ */

包含源文件:

/*
 * Block.cpp
 *
 *  Created on: 11 Mar 2015
 *      Author: Edward
 */

#include "Block.hpp"

#define DEFAULT_PORTNUM 3   // COM3
#define DEFAULT_BAUDNUM 1  //  1Mbps

Block::Block(BasicRobotFunctions basic) {
    grounded = false;
    number = Block::lookAround(basic);
}

Block::~Block() {}

void Block::setGrounded(bool ground){
    grounded = ground;
}
/*
void Block::setPosition(int x, int y){
    position.x = x;
    position.y = y;
}*/

void Block::setDistance(int dist){
    distance = dist;
}

void Block::setNumber(int num){
    number = num;
}

bool Block::getGrounded(){
    return grounded;
}
/*
pos Block::getPosition(){
    return position;
}*/

int Block::getNumber(){
    return number;
}

int Block::getDistance(){
    return distance;
}

int Block::getBrightness(){
    return object_brightness;
}

//TODO Arrange function to incorporate Turn() in BasicRobotFunctions
int Block::lookAround(BasicRobotFunctions basic){
    int num = 0;
    dxl_initialize(DEFAULT_PORTNUM,DEFAULT_BAUDNUM);
    for(int i = 0;i<360;i++){
        dxl_write_word(11,32,-255);
        dxl_write_word(11,30,200);
        basic.Step(1);
        dxl_write_word(11,32,255);
        dxl_write_word(11,30,100);
        if(dxl_read_byte(100,32) >= dxl_read_byte(100,52)){
            num++;
        }
    }
    dxl_terminate();
    return num;
}

void Block::setBrightness(int bright){
    object_brightness = bright;
}

然而,我从构造函数和turnAround(BasicRobotFunctions)方法收到以下编译错误:

In file included from Robot.hpp:11,
                 from BasicRobotFunctions.hpp:12,
                 from main.cpp:8:
Block.hpp:23: error: expected `)' before 'basic'
Block.hpp:35: error: 'BasicRobotFunctions' has not been declared
make.exe: *** [main.o] Error 1

使用对象作为变量检查了我的其他类后,我得到了同样的错误。 针对报价中的要点:   - 包括BasicRobotFunctions.hpp   - 在提及它的所有不同实例中,类名拼写相同   - 我没有复制粘贴任何夹杂物   - 我没有在项目中使用任何名称空间   - 我也不使用任何模板   - 文件名在我的include中拼写错误   - 我还没有在程序中定义任何宏   - 我确保每个类都在自己的头文件中定义

我的系统可能有任何其他问题,我做的任何错误,或者我在做什么,这是不好的编程习惯吗?

2 个答案:

答案 0 :(得分:1)

问题的原因:

您有一个头文件循环依赖问题。

main.cpp包括BasicRobotFunctions.hpp
其中包括Robot.hpp
其中包括Block.hpp
其中包括BasicRobotFunctions.hpp

如果你的头文件被正确保护以防止多次包含(它们似乎是这样),Block.hpp不会看到BasicRobotFunctions.hpp的定义,因为它已经在包括它


如何发现问题:

此问题的根源在编译错误消息和Block.hpp文件中很明显。

编译器报告了Block.hpp中的错误,它正在逐行描述它是如何通过包含进入该文件的。 Block.hpp文件的来源清楚地表明它正在尝试包含BasicRobotFunctions.hpp


修复:

在您的情况下,您可以修改Block.hpp中的方法签名以使用BasicRobotFunctions类型的(可能是常量)引用,然后转发声明类型。这允许您消除对BasicRobotFunctions.hpp头文件的依赖性。 (Block.cpp可能需要同时包含Block.hppBasicRobotFunctions.hpp。)

//...
#include "typedefinitions.h"
#include "dynamixel.h"

class BasicRobotFunctions; // Forward declaration

    //...
    Block(const BasicRobotFunctions &basic);
    //...
    int lookAround(const BasicRobotFunctions &basic);
    //...

将来可以通过最小化允许头文件编译所需的标头来避免此问题。这意味着您的头文件应该:

  • 将前向声明用于所使用的类型。
  • 使用引用转发声明的类型。

您可以通过确保它自己编译来检查您的头文件是否已最小化其依赖项。我首先将头文件包含在相应的源文件中,然后确保源文件编译。

// Foo.cpp
#include "Foo.hpp"
//...

答案 1 :(得分:0)

那么你可以在课前作为

提出前瞻性声明

class BasicRobotFunctions; class Block { public: bool grounded; //TODO position is a ...

但是这种错误意味着#include“BasicRobotFunctions.hpp” 不要声明BasicRobotFunctions。代码守卫可能会遇到麻烦吗? 圆形包含可以使用前向声明来解决,在标题中放入正确的保护并将一些包含移动到源文件。