为什么我会收到链接器错误?
/*
test.cpp
© Andrey Bushman, 18 Jun 2013
*/
//--------------------------------------------
#include <exception>
#include <iostream>
using namespace std;
//--------------------------------------------
namespace Bushman{
//--------------------------------------------
class MyClass{
public:
MyClass();
};
//--------------------------------------------
MyClass::MyClass(){
void func(); // declaration
func(); // call
}
//--------------------------------------------
void func(){ // definition
cout << "Ping..." << endl;
}
}
//============================================
int main()
try{
namespace B = Bushman;
B::MyClass a;
}
catch(exception& e){
cerr << e.what() << endl;
return 1;
}
catch(...){
cerr << "Unknown exception." << endl;
return 2;
}
结果(由MS Visual Studio 2012提供):
C:\bs\13>cl test.cpp /EHsc
Microsoft (R) C/C++ Optimizing Compiler
Version 17.00.51106.1 for x64 Copyright (C) Microsoft Corporation. All
rights reserved.
test.cpp
Microsoft (R) Incremental Linker Version 11.00.51106.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:test.exe test.obj test.obj : error LNK2019: unresolved external
symbol "void __cdecl func(void)" ( ?func@@YAXXZ) referenced in
function "public: __cdecl Bushman::MyClass::MyClass( void)"
(??0MyClass@Bushman@@QEAA@XZ) test.exe : fatal error LNK1120: 1
unresolved externals
C:\bs\13>
谢谢。
答案 0 :(得分:3)
namespace Bushman{
MyClass::MyClass(){
void func(); // declaration
func(); // call
}
//--------------------------------------------
void func(){ // definition
cout << "Ping..." << endl;
}
}
您在func()
构造函数中声明MyClass
。此应与您在func()
命名空间中定义的Bushman
相同;但看起来您的编译器出错了。通常在另一个函数内部或构造函数内声明函数被认为是不好的做法。相反,您应该直接在您打算使用的范围内声明函数。在这种情况下,您需要func()
命名空间中的Bushman
前向声明:
namespace Bushman{
void func(); // declaration
MyClass::MyClass(){
func(); // call
}
//--------------------------------------------
void func(){ // definition
cout << "Ping..." << endl;
}
}
或者,您可以将代码拆分为单独的.h和.cpp文件。实际上,这是理想的。我建议将func()
放入func.cpp
,并在func.h
中加上声明。同样,将MyClass
声明放在myclass.h
中,将MyClass
声明放在myclass.cpp
中。现在myclass.cpp
应该`#include“func.h”。
使用头文件,这种方式可以对前向声明进行微调,并确保在需要时定义所有内容。
答案 1 :(得分:3)
看起来你的编译器错误地将名称引入全局命名空间,而不是C ++ 11 3.5 / 7指定的最里面的封闭命名空间(Bushman
):
当找不到具有链接的实体的块范围声明来引用其他声明时,该实体是最内层封闭命名空间的成员。
代码在GCC上按预期编译:http://ideone.com/PR4KVC
您应该能够通过在构造函数的块作用域中声明它之前(或代替)声明该函数来解决该错误。但是,我无权访问您的编译器来测试它。
答案 2 :(得分:1)
你宣布了一项功能
void func()
阴影方法
void MyClass::func()
所以你的调用是调用未定义的函数,而不是方法。