【发布时间】:2017-08-30 21:10:20
【问题描述】:
我编写了一些代码,试图了解编译和链接之间的关系 - 并查看函数声明在源文件中的何处以及是否必须重复。
我写的两个文件是:
Person.cpp:
#include <string>
class Person {
public:
Person(std::string name) {
(*this).name = name;
};
std::string getName() {
return name;
};
std::string name;
};
和文件
PersonMain.cpp:
#include <iostream>
class Person {
public:
Person(std::string);
std::string getName();
std::string name;
};
int main(){
Person* charlie = new Person("Charlie");
std::cout << "Hi, my name is " << charlie->getName();
}
我在 PersonMain.cpp 中重复了 Class Person 和 Class Person 函数声明(不是定义)。
我现在使用 gcc C++ 编译器编译和链接这两个文件:
g++ *.cpp -o runthis.exe
然后我收到以下错误消息:
PersonMain.cpp:(.text+0xfe): 未定义的引用
Person::Person(std::basic_string<char, std::char_traits<char>,std::allocator<char> >)' PersonMain.cpp:(.text+0x13c): undefined reference toPerson::getName()' collect2.exe: error: ld 返回 1 个退出状态
链接时似乎找不到 Person 类方法。这是为什么?我怎样才能治愈它?
附录:
我在 PersonMain.cpp 中明确地重复了 Person 的声明,但并没有像通常那样将其重新声明到头文件中。所以我已经在这里完成了预处理器步骤。 This faq 建议:
[预处理器] 一次处理一个 C++ 源文件,方法是替换 包含相应文件内容的指令(通常只是声明)[...]
及以后:
[链接器]通过替换引用来链接所有目标文件 具有正确地址的未定义符号。这些符号中的每一个 可以在其他目标文件或库中定义。
我添加此注释是因为@engf-010 表示即使其他编译单元中需要它,也不会编译具有该编译单元中实际未使用的代码的编译单元。 enf-010建议我把定义和声明放到头文件中,但是faq文章说只有声明应该放在那里,定义可以放在别处。
【问题讨论】:
-
请阅读
const -
你有两个名为 Person 的类。
-
在这种情况下你会得到一个重新定义错误。
-
@LogicStuff 但我只是在 PersonMain 中重新声明而不是重新定义 Person。重复声明没问题,我想。定义在 Person 中,这是链接器应该寻找它的地方。通常,所有的重新声明都在一个头文件中,但我明确地把它们放在里面。
-
呃,请至少正确格式化这个混乱。