【问题标题】:Which class should be used by C++?C++ 应该使用哪个类?
【发布时间】:2015-03-30 13:38:31
【问题描述】:

我觉得描述起来有点棘手。但我尽力了……

给定:

一个编(Prog_A)

一个库(Lib_A) 一个类 Class_A

还有一个带有(也)类 Class_A 的库(Lib_B)和一个成员 Class_A mClass_A

Class_A 两个类都有功能

void Class_A::DoSome(){
...
}

然后对于 Lib_A 中的 Class_A

void Class_A::DoSome(){
std::cout << "LIB_A";
}

然后对于 Lib_B 中的 Class_A

void Class_A::DoSome(){
std::cout << "LIB_B";
}

Prog_A 包括 Lib_A,Lib_A 包括 Lib_B。 Lib_A 和 Lib_B 由回调“连接”。 如果我现在在 Lib_B 中调用 mClass_A.DoSome() 那么它正在打印

LIB_A

而不是我的期望“LIB_B”。

这种行为是否正确,还是我必须担心?

【问题讨论】:

  • 详细了解virtual成员函数和vtables
  • linux真的跟这个问题有关系吗?使名称不同或使用命名空间以使使用更清晰。
  • 这更多地与 .ELF 可执行格式有关,而不是与 Linux 本身有关。为此,C++ 使用所谓的“弱符号”。这些可以在过程映像中出现“多次”。每个库都可以定义相同名称的符号,但第一个获胜。 PS:这不是您问题的答案。关于名称修改和符号映射到 .ELF 格式的真正答案会很长。
  • @BasileStarynkevitch 这个问题与虚拟成员函数和 vtables 无关。这是一个模棱两可的命名问题。
  • @ibre5041,上述场景中不会出现弱符号。弱符号用于内联函数和 temploid,但并非用于 C++ 中的每个符号。也许你想到的是 ELF 符号插入,它独立于弱符号。

标签: c++ class


【解决方案1】:

您的代码错误。您已经定义了两次Class_A,但定义不匹配。

这是不允许的

[C++11: 3.2/3]: 每个程序都应包含该程序中 odr 使用的每个非内联函数或变量的确切定义;不需要诊断。 定义可以显式出现在程序中,可以在标准或用户定义的库中找到,或者(在适当时)隐式定义(参见 12.1、12.4 和 12.8)。内联函数应在使用它的每个翻译单元中定义。

[C++11: 3.2/5]: 类类型可以有多个定义(第 9 条)、枚举类型(7.2)、带外部链接的内联函数(7.1.2)、类模板( Clause 14)、非静态函数模板 (14.5.6)、类模板的静态数据成员 (14.5.1.3)、类模板的成员函数 (14.5.1.1) 或某些模板参数不适用的模板特化在程序中指定(14.7、14.5.5)只要每个定义出现在不同的翻译单元中,并且定义满足以下要求。给定这样一个名为 D` 的实体在多个翻译单元中定义,那么

  • D 的每个定义都应包含相同的标记序列
  • [..]

如果您直接构建整个程序,您会在链接时遇到多重定义错误;但是,由于您是动态链接,因此这是不可能的,您的程序只是被破坏了。

使用命名空间将定义彼此分开。

我在共享库中使用a custom boost::lexical_cast specialisation I'd found on Stack Overflow 时意外地导致了这个问题,没有意识到原始的“默认”特化已在单独的共享库中实例化。我从主应用程序中得到的行为非常不可预测。

【讨论】:

  • 大家好,谢谢大家!主要是我不确定我是否犯了错误并且我“重定向”了未知,或者在这种情况下,这是一种正常行为。所以,一切顺利。同时,我更改了一个类名,这与使用命名空间“相同”。但很高兴知道未来。非常感谢大家!问候早食
猜你喜欢
  • 2012-11-23
  • 2018-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-08
  • 2011-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多