在下面的示例中,为什么我必须完全限定cpp中自由函数的名称以避免链接器错误,为什么它不适用于类函数?你能解释一下这个区别吗?
的 ctest.h: 的
namespace Test
{
int FreeFunction();
class CTest
{
public:
CTest();
~CTest();
};
}
的 ctest.cpp: 的
#include "ctest.h"
using namespace Test;
// int FreeFunction() -> undefined reference error
int Test::FreeFunction() -> works just fine
{
return 0;
}
CTest::CTest() -> no need to fully qualify name, i.e. Test::CTest
{}
CTest::~CTest()
{}
感谢您的时间和帮助
答案 0 :(得分:12)
int FreeFunction(void);
只是一个声明,而下面是一个定义。
class CTest
{
public:
CTest();
~CTest();
};
如果您想提供definition for an already declared entity in a namespace
(例如在封闭的命名空间中),则必须是完全限定名称。
EDIT2:
这是一些可以让你更清晰的东西。请注意此代码中没有using指令。
namespace Test {
int FreeFunction(void); // declare
class CTest; // declare
}
int Test::FreeFunction(){return 0;} // define
class Test::CTest{ // define
};
int main(){}
编辑3:声明与定义(C ++ 0x) $ 3.1 / 2-
声明是的定义,除非 它声明了一个没有的函数 指定函数的主体 (8.4),它包含extern 说明符(7.1.1)或a 连锁规范25(7.5)和 无论是初始化者还是初始化者 函数体,它声明了一个静态 类定义中的数据成员 (9.4),它是一个类名 声明(9.1),它是一个 opaque-enum-declaration(7.2),或者它 是一个typedef声明(7.1.3),a 使用声明(7.3.3),a static_assert-declaration(第7条), 属性声明(第7条), 空声明(第7条)或a using-directive(7.3.4)。
答案 1 :(得分:2)
FreeFunction
如果在提供Test::FreeFunction
行后引用它或,将解析为using namespace Test;
,而定义< / em>函数去了,编译器无法知道你是否在任何命名空间之外定义全新函数 FreeFunction
,或者你是否定义了已经声明的{ {1}}。编译器默认认为您正在定义一个全新的函数。
对于Test::FreeFunction
,您已经引用了类CTest::CTest
,并且因为Test::CTest
之外没有类CTest
1}}命名空间,对Test
的引用是明确的。所以它知道构造函数和析构函数定义引用了命名空间类CTest::anything
。
我认为这是一个很小的代价,必须写CTest
。
希望这有帮助!
答案 2 :(得分:1)
如果你没有限定FreeFunction定义,那么编译器肯定不知道你想要为先前正向声明的Test :: FreeFunction或当前命名空间中的单独FreeFunction提供实现。
另一方面,只有一种方法可以解析名称CTest - 作为Test命名空间中的类定义。因此,没有必要完全符合它。
但是,如果CTest名称解析是不明确的(比如当前命名空间中还有另一个CTest类),则必须完全限定方法声明。
答案 3 :(得分:0)
实现函数时,我发现打开命名空间通常是可取的。记住你可以重新打开它们......
// in Test.cpp
namespace Test
{
int FreeFunction()
{
return 0;
}
}