假设我们有很多关于课堂和课程的heasders,就像这样:
// header.h
#ifndef MYHEADER
#define MYHEADER
class myClass {
public:
int one()
{
return 1;
}
int two();
};
#endif // MYHEADER
以及一些带有一些函数实现的cpp文件:
// header_impl.cpp
#include "header.h"
int myClass::two()
{
return 2;
}
将进入.lib(.a)库包获得int one()
的实现,否则它将保留在头文件中并且仅在有人使用lib的情况下编译,因此这个头文件倾向于在代码中使用它(并且会被编译成他的代码但是更新会出现在.lib(.a)文件中吗?
在头文件中定义的函数实现编译成静态库吗?
答案 0 :(得分:1)
假设任何库函数本身都没有使用该函数,并且没有库函数获取其地址[生成函数指针],那么编译器没有理由对其进行“实际功能”。当然,由于内联实际上是“编译器决定”的问题,因此编译器完全有可能决定不使用内联函数,实际上在编译它的目标文件中创建一个。
但一般来说,对于小函数,不,它只会在标题中作为源代码存在,然后在调用它的任何地方都会内联。
答案 1 :(得分:1)
也许,因为cpp
几乎肯定会在静态库中包含该标头。通常只是因为它在类中定义并不强制它是内联的,但它确实指明该函数有一个ODR异常(我认为我称之为内联链接;稍后会详细介绍)。因此,根据函数及其在静态库中的使用,它可能有也可能没有实际定义,具体取决于编译器是否内联它以及是否正在使用它。
如果编译器决定不内联你的函数,当你#include
那个与静态库链接的exe
标题时,你可能认为应该再次定义它,并打破一个定义规则。但是,你错了。因为该方法在类体内定义的事实将该函数标记为具有ODR预期。最终,编译器将选择哪个定义(静态库中的定义或exe
/中的定义)。可能会选择它看到的第一个。
注意:您可以通过在类体外定义函数并使用inline
关键字来实现ODR异常。