代码之家  ›  专栏  ›  技术社区  ›  nabulke

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

  •  7
  • nabulke  · 技术社区  · 15 年前

    在下面的示例中,为什么我必须完全限定cpp中自由函数的名称以避免链接器错误,为什么它对没有链接器的类函数有效?你能解释一下区别吗?

    cTest.h:

    namespace Test
    {
        int FreeFunction();
    
        class CTest
        {
            public:
                CTest();
                ~CTest();
        };
    }
    

    CPTP.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 回复  |  直到 15 年前
        1
  •  11
  •   Chubsdad    15 年前
    int FreeFunction(void);  
    

    只是一个声明,而下面是一个定义。

    class CTest 
    { 
        public: 
            CTest(); 
            ~CTest(); 
    }; 
    

    如果你想提供 definition for an already declared entity in a namespace (例如,在封闭的命名空间中),它必须是完全限定名。

    编辑2:

    这是一些能让你更清楚的东西。注意:此代码中没有使用指令。

    namespace Test { 
        int FreeFunction(void);   // declare
    
        class CTest;              // declare
    } 
    
    int Test::FreeFunction(){return 0;} // define
    class Test::CTest{            // define
    };
    
    int main(){}
    

    编辑3:声明vs定义(C++0X) 3.1/2美元

    声明是定义 除非 它声明的函数没有 指定函数的主体 (8.4) ,它包含外部 说明符(7.1.1)或 连杆-规格25(7.5)和 初始值设定项和 函数体,它声明一个静态 类定义中的数据成员 (9.4) 它是一个类名 声明(9.1) 这是一个 不透明枚举声明(7.2),或 是typedef声明(7.1.3),a 使用声明(7.3.3),a 静态声明(第7条) 属性声明(第7条) 空声明(第7条),或 使用指令(7.3.4)。

        2
  •  1
  •   Franci Penov    15 年前

    如果不限定freefunction定义,则编译器不确定要为先前正向声明的test::freefunction或当前命名空间中单独的freefunction提供实现的其他程序。

    另一方面,只有一种方法可以将名称ctest解析为测试命名空间中的类定义。因此,不需要完全限定它。

    但是,如果ctest名称解析不明确(例如当前命名空间中也有另一个ctest类),则必须完全限定方法声明。

        3
  •  1
  •   btown    15 年前

    同时 FreeFunction 将决心 Test::FreeFunction 如果你 参考它或叫它 在提供 using namespace Test; 线,尽可能 定义 函数执行时,编译器无法知道您是否在定义 全新功能 自由函数 在任何命名空间之外,或者是否定义已声明的 测试::自由函数 . 编译器默认认为您正在定义一个全新的函数。

    为了 CTest::CTest 但是,你已经 提到 班级 Test::CTest 因为没有类或命名空间 CTest 在外面 Test 命名空间,嗯,对 CTest::anything 是明确的。因此,它知道构造函数和析构函数定义引用命名空间中的类 克雷斯特 .

    我认为这是一个很小的代价,必须写 测试::自由函数 .

    希望这有帮助!

        4
  •  0
  •   CashCow    15 年前

    我发现,在实现函数时,最好打开名称空间。记住你可以重新打开它们…

    // in Test.cpp
    namespace Test
    {
       int FreeFunction()
       {
           return 0;
       }
    }
    
    推荐文章