C ++未定义的引用错误

时间:2012-07-08 07:10:20

标签: c++ namespaces extern undefined-reference

首先,一个更抽象的问题。当你不需要构造函数/析构函数或所述对象的多个副本时,在速度方面使用命名空间而不是类是一种好习惯吗?

其次,我得到“ccEaV3B0.o:main.cc :(。text + 0x10):在尝试包含和使用命名空间时对`board :: arbi'的未定义引用。我在Windows 7上使用Mingw32,使用make命令:g ++ -Wall main.cc board.cc

当我单独编译时,也会发生这种情况,使用: g ++ -c board.cc g ++ -Wall main.cc board.o

以下是(最小)文件:

main.cc:

#include <iostream>
using namespace std;

#include "board.h"

int main(){
    cout << board::give() << endl;
    return 0;
}

board.h:

#ifndef BOARD_H
#define BOARD_H

namespace board {
    extern int arbi;
    extern int give();
}

#endif

board.cc:

#include "board.h"

int board::give(){
    return arbi;
}

通过初始化“int board :: arbi = 5;”解决在board.cc

问题仍然是为什么当某个东西显然是一个对象时你应该使用一个类,即使你知道所有对象的确实只有一个实例。在我看来,你会想要全局变量,但为了避免名字冲突,你可以将它们放在命名空间中。

2 个答案:

答案 0 :(得分:3)

您尚未定义board::arbi。这可能是你未定义的参考。

至于namespaceclass,它们有不同的用途。 class为实例化或从中派生的一组对象提供一组属性。 namespace是一种提供具有公共前缀的符号集合的方法。它不是作用域(虽然命名空间解析类似于作用域),并且没有继承或派生自namespace

范围可以限制其中的名称的可见性。 namespace不提供隐藏在常规变量可用范围之外的任何可见性(例如文件静态变量)。 class可以创建privateprotected数据成员和方法的位置。

答案 1 :(得分:3)

您需要在board.cc文件中定义board :: arbi。

 int board::arbi = <whatever initial value>;

使用extern声明你只是安慰编译器,你将在稍后提供定义,但你没有提供。

关于抽象问题,类和命名空间的概念是非常不同的。类定义了“真实”对象的结构。我,他们占据了记忆。命名空间就像一个限制全局变量范围的围栏。它们不占用内存....因此,如果您在程序中看到逻辑对象将它们定义为类。但是,如果您只看到一组以某种方式相关的全局函数,但您无法将它们想象为一个连贯的对象,请使用命名空间。