c ++: «Переопределить» внешние переменные пространства имен в .cpp - PullRequest
0 голосов
/ 13 мая 2019

Я новичок в c ++ и наткнулся на этот код:

file.h

namespace Type
{
   typedef BOOL (WINAPI *TYCopyFile)
   (
    PCHAR lpExistingFileName,
    PCHAR lpNewFileName,
    BOOL  bFailIfExists
   );
}

namespace Func
{
  extern Types::TYCopyFile pCopyFileA;
}

file.cpp

namespace Funcs
{
  Types::TYCopyFile pCopyFileA;
}

void Init
{
  Funcs::pCopyFileA = (Types::T_CopyFile) GetProcAddress(hKernel32, "CopyFileA");
}

Идея очень проста. У меня есть пространство имен typedef (Types) и я создаю указатель на функцию в другом пространстве имен (Funcs) как extern. Затем я определяю этот указатель на функцию в File.cpp в функции Init.

Вопрос, который у меня возникает, заключается в том, почему мне нужно переопределить namespace Funcs в File.cpp? Почему я не могу просто использовать функцию Init, которая инициализирует Funcs::pCopyFileA? Как я понимаю extern, он сообщает компилятору, что переменная где-то существует, и указывает компоновщику найти его. Почему компоновщик не может найти его без namespace Funcs в File.cpp?

1 Ответ

1 голос
/ 13 мая 2019

Для всех символов в C ++ вам нужно и объявление , и определение .Заголовочный файл содержит объявление Func::pCopyFileA, исходный файл содержит определение.

Если вы определите переменную в заголовочном файле (то есть удалите ключевое слово extern), тогда определение будет сделано ввсе единицы перевода , которые включают файл заголовка.Это нарушает правило одного определения и приведет к ошибкам множественного определения при связывании.

...