我是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
的链接器找不到它?
答案 0 :(得分:1)
对于C ++中的所有符号,您都需要一个声明和一个定义。头文件包含Func::pCopyFileA
的声明,源文件包含定义。
如果您在头文件中定义了变量(即删除了extern
关键字),则将在所有包含头文件的translation units中进行定义。这会破坏one definition rule,并且在链接时会导致多定义错误。