【发布时间】:2009-03-02 18:16:48
【问题描述】:
ISO C++ 说,C++ 中成员函数的内联定义与用内联声明它是一样的。这意味着该函数将在使用该成员函数的每个编译单元中定义。但是,如果函数调用由于某种原因不能被内联,则函数将“像往常一样”被实例化。 (http://msdn.microsoft.com/en-us/library/z8y1yy88%28VS.71%29.aspx) 我对这个定义的问题是它没有说明它将在哪个翻译单元中被实例化。 我遇到的问题是,当面对单个静态库中的两个目标文件时,它们都引用了一些无法内联的内联成员函数,链接器可能会“选择”任意目标文件作为定义的源。这种特殊的选择可能会引入不需要的依赖关系。 (除其他外)
例如: 在静态库中
A.h:
class A{
public:
virtual bool foo() { return true; }
};
U1.cpp:
A a1;
U2.cpp:
A a2;
还有很多依赖
在另一个项目中 main.cpp:
#include "A.h"
int main(){
A a;
a.foo();
return 0;
}
第二个项目是指第一个项目。我如何知道编译器将使用哪个定义,以及哪些目标文件及其依赖项将被链接?标准对此有什么规定吗? (试过了,没找到)
谢谢
编辑:因为我看到有些人误解了问题是什么,所以我想强调一下:如果编译器决定为该函数创建一个符号(在这种情况下,它会,因为“虚拟性”,在不同的目标文件中会有几个(外部可见的)实例化,链接器会选择哪个定义(从哪个目标文件?)
【问题讨论】:
-
定义什么?为什么 a1 和 a2 在那里?你只有一个 A 类的定义。
-
A::foo 的定义,因为它不能被内联(作为一个虚拟,它必须至少有一个外部定义)
-
这不是因为“虚拟性”;正是因为“内联”,才会有多个定义。
-
我实际上是在谈论实例化。 (如在具有链接器可见符号的二进制代码中)抱歉造成混淆。
标签: c++ inline-method