Пространства имен, классы и бесплатные функции - когда вам нужны полностью квалифицированные имена

StackOverflow https://stackoverflow.com/questions/4084972

Вопрос

В моем примере ниже, зачем мне полностью квалить имя свободной функции в 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()
{}

Спасибо за ваше время и помощь.

Это было полезно?

Решение

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), он содержит спецификатор Extern (7.1.1) или спецификацию ссылок25 (7.5), а также инициализатор, ни функциональный корпус, он объявляет статический элемент данных в определении класса (9.4), Это объявление имени класса (9.1), это непрозрачный-enum-декларация (7.2), или это объявление Typedef (7.1.3), использование-декларация (7.3.3), static_assert-декларация (пункт 7), объявление атрибута (предложение 7), пустое объявление (пункт 7) или используемая Директива (7.3.4).

Другие советы

Пока FreeFunction будет разрешаться Test::FreeFunction если ты обратитесь к этому или позвоните После предоставления using namespace Test; линия, насколько определяющий Функция идет, компилятор не имеет способов знать, если вы определяете совершенно новая функция FreeFunction вне любого пространства имен, или определяете ли вы уже объявленные Test::FreeFunction. Отказ Компилятор по умолчанию должен думать, что вы определяете совершенно новую функцию.

За CTest::CTest, Однако, однако, вы уже ссылаясь на класс Test::CTest, и так как нет класса или пространства имен CTest вне Test пространство имен, ну, ссылка на CTest::anything недвусмысленно. Таким образом, он знает, что определения конструктора и деструктора относятся к классу пространства In-Image CTest.

Я думаю, что это небольшая цена, чтобы заплатить, чтобы написать Test::FreeFunction.

Надеюсь это поможет!

Если вы не вводите определение Freefunction, компилятор точно не знает, что вы хотите предоставить реализацию для ранее переполненного теста :: Freefunction или для отдельной бесплатной записи в текущем пространстве имен.

С другой стороны, есть только один способ разрешить имя CTEST - как определение класса из пространства имен тестирования. Таким образом, нет необходимости полностью квалифицировать его.

Однако, если разрешение имени CTEST неоднозначно (скажем, есть еще один класс CTEST в текущем пространстве имен), вам придется полностью квалифицировать декларации методов.

При внедрении функции обычно предпочтительнее, я нахожу, чтобы открыть пространство имен. Помните, что вы можете восстановить их ...

// in Test.cpp
namespace Test
{
   int FreeFunction()
   {
       return 0;
   }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top