【发布时间】:2017-01-09 00:31:21
【问题描述】:
我有一个由两个类实现的纯虚方法的基类:
// base_class.hpp
class base_class {
public:
virtual std::string hello() = 0;
};
// base_implementer_1.hpp
class base_implementer1 : base_class {
public:
std::string hello();
};
// base_implementer_2.hpp
class base_implementer2 : base_class {
public:
std::string hello();
};
// base_implementer_1.cpp
std::string hello() {
return(std::string("Hello!"));
}
// base_implementer_2.cpp
std::string hello() {
return(std::string("Hola!"));
}
请注意在实现中缺少base_implementer1:: 和base_implementer2::。这是故意的。
通过添加base_implementer1:: 和base_implementer2::,我没有收到多重定义错误。但是,将它们从链接器中删除会抱怨我对同一函数有两个定义 (hello())。
由于头文件中没有这两个实现,我认为(即使它们在实际实现 hello() 方面是不正确的)它们是被允许的,因为没有理由你不能有两个 @ 987654328@ 在两个不同的.cpp 文件中起作用。但情况似乎并非如此。谁能告诉我链接器中发生了什么导致这个多重定义错误发生?
【问题讨论】:
-
“因为没有理由在两个不同的 .cpp 文件中不能有两个 hello() 函数”——是的,有。链接器看到两个具有相同签名的函数 - 这是一个多重定义。
-
您可以在两个不同的 .cpp 文件中拥有两个
hello(),但不能将它们链接在一起。否则,当调用hello()时(例如在main.cpp中)应该使用哪个定义? -
仅仅因为您的
hello实现在base_implementer_1.cpp 中并不意味着它是base_implementer_1类的一部分。只有当您用base_implementer_1::假装hello时,它才会成为课程的一部分。base_implementer_2也是如此。换句话说,你故意没有在方法实现前加上类名是你的问题。 -
请发布 MCVE。当前代码将无法编译,因为
std未定义。 -
@M.M 这是一个说明概念的玩具示例。它的编译能力并不能增强对手头问题的理解。我们可以想象这些文件被声明在一个包含必要的
#includes(等)的地方
标签: c++ linker one-definition-rule