Class 在 C++ 库和程序中具有相同的接口。 exe版本是

Class with same interface in c++ lib and program. Exe version is

我有一个静态库,它有一个 class 栏,在 c++ 库和程序的头文件中定义了相同的接口。该 exe 具有略微不同的 Bar.cpp 源代码,并创建具有不同值的对象。请参阅下面的代码。

静态库文件。 (Lib_project\Foo_lib)

Lib_project\foo_lib.h

class Foo
{
public:
    int printBarA() const;
};

Lib_project\foo_lib.cpp

#include <iostream>
#include "Foo_lib.h"
#include "Bar.h"

int Foo::printBarA() const
{
    Bar bar;
    std::cout << "bar.getA() : " << bar.getA() << std::endl;
    return 0;
}

Lib_project\Bar.h

// Lib Bar definition
class Bar
{
public:
    Bar();
    int getA() const;
private: 
    int a;
};

Lib_project\Bar.cpp

#include "Bar.h"

Bar::Bar() : a(99) {}  // Different value here
int Bar::getA() const { return a; }

主程序exe代码(shared_class)

Bar.h

// exe Bar definition
class Bar
{
public:
    Bar();
    int getA() const;
private:
    int a;
};

bar.cpp

#include "Bar.h"

Bar::Bar() : a(66) { }  // Different value here
int Bar::getA() const { return a; }

main.cpp

#include "Lib_project\Foo_lib.h"

int main(int argc, char** argv)
{
    Foo foo;
    foo.printBarA();
    return 0;
}

编译后的程序输出如下。 Foo_lib 方法 Foo::printBarA() 根据 main.exe Bar.cpp 中定义的 a=66 创建 Bar 对象;而不是在具有 a=99 的库 Bar.cpp 中定义;

D:\shared_class>Release\shared_class.exe
bar.getA() : 66

编译为 DLL 在 windows 上修复了它,但在 linux 上作为共享库问题仍然存在,所以我需要一个独立于平台的修复。

所以我的问题是:

  1. 为什么会这样? (我正在考虑如何处理被丢弃的 .obj 文件 在 link 时间。)
  2. 我有什么选择可以停止此行为,以便使用 Foo_lib.lib 中的 Bar.cpp 并打印 bar.getA() : 99?
    • 将所有库文件包装在命名空间中?或者重命名 classes?我有 实际案例中有很多文件。有没有 linker 或编译器 比可行的选项?

谢谢

分辨率:

我必须将每个 class 包装在命名空间中以避免任何冲突。现在一切都按预期工作。

您在同一程序中使用相同的 class (::Bar) 和两个略有不同的定义,这违反了单一定义规则 (ODR)。您的程序的行为完全未定义。

要解决此问题,您必须重命名 Bar 的一个定义,方法是更改​​实际名称或将其放入命名空间。

(至于为什么会发生这种情况的技术细节,这是由于链接器使用静态库来解决依赖关系的方式。但由于它是 UB,因此您不能依赖它。)