名称空间,类和自由函数 - 何时需要完全限定名称

时间:2010-11-03 07:34:13

标签: c++ namespaces declaration definition fully-qualified-naming

在下面的示例中,为什么我必须完全限定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()
{}

感谢您的时间和帮助

4 个答案:

答案 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;
   }
}