我在 Visual Studio 2008 C++ 编译器中遇到了以下烦人且看似不正确的行为:
假设我有一个类库 - Car.lib - 它使用“Car”类,头文件名为“Car.h”:
class Car
{
public:
void Drive()
{
Accelerate();
}
void Accelerate();
};
我实际上想要做的是使用 Car 标头(用于其他一些功能),但不必与 Car.lib 本身链接(实际的类不称为“Car”,但我正在清理这个示例)。
如果我在用于构建托管 C++ .dll 的 .cpp 文件中#include "Car.h",但从不引用 Car,则一切都可以编译和链接。这是因为我从不实例化 Car 对象。
但是,以下内容:
namespace {
class Car
{
public:
Car(const Car& rhs)
{
Accelerate();
}
void Accelerate();
};
}
给我留下链接错误:
Error 2 error LNK2001: unresolved external symbol "public: void __thiscall `anonymous namespace'::Car::Accelerate(void)" (?Accelerate@Car@?A0xce3bb5ed@@$$FQAEXXZ) CREObjectWrapper.obj CREObjectBuilderWrapper
请注意,我已经在匿名命名空间中声明了整个内容,因此在任何情况下都无法从 .DLL 中导出 Car 函数。
我可以肯定地保证 Car 不会在其他任何地方被引用,因为我只是创建了这个类并从 scatch 中输入了定义。“真正的”类是一个不同的名称。
离线声明复制构造函数没有区别。即以下也无法链接:
class Car
{
public:
Car(const Car& rhs);
void Accelerate();
};
Car::Car(const Car& rhs)
{
Accelerate();
}
这与复制构造函数注释特别有关,因为例如,以下内容确实链接:
class Car
{
public:
Car()
{
Accelerate();
}
void Accelerate();
};
我不是 C++ 标准专家,但这对我来说似乎不正确。当然,编译器仍然不必生成任何调用 Car 复制构造函数的代码。
谁能确认这种行为是否正确?自从我使用 C++ 以来已经有一段时间了——但我不认为这曾经是 Visual Studio 6.0 的问题。
这可能是因为我正在构建一个托管 C++ .dll。(后来:是的,这正是问题所在。 /clr 选项似乎引入了这种依赖关系)。
这是用于构建项目的命令行:
/OUT:"..\..\bin\Release\CREObjectBuilderWrapper.dll" /INCREMENTAL:NO /NOLOGO /LIBPATH:"..\..\lib\qa\lib" /LIBPATH:"..\..\lib\release" /LIBPATH:"..\..\lib\VDB" /DLL /MANIFEST /MANIFESTFILE:"Release\ObjectBuilderWrapper.dll.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"c:\Release\ObjectBuilderWrapper.pdb" /LTCG /DYNAMICBASE:NO /FIXED:No /MACHINE:X86 /KEYFILE:"c:\src\ObjectBuilderWrapper\\FI.snk" /ERRORREPORT:PROMPT CRERuntime.lib QA.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
任何人都可以提出一种解决方法,允许从复制构造函数中“重用”Accelerate 方法并且仍然将复制构造函数声明为内联?