“一处定义原则” 是 C++ 为了避免程序在编译和链接过程中出现重复定义错误而设定的规则
程序级别只有一处定义:一般函数
翻译单元级别只有一处定义:内联函数、类、模板
一个源文件被分为多个源文件,这多个源文件ABC中,ABC每个单独源文件内中不能定义相同的内联函数、类、模板,好比两个相同内联函数inline void func1()在同一个源文件中这种情况不允许,但同一个内联函数inline void func1()可以分别出现在A、B、C中
程序级别只有一处定义:一般函数:在整个 C++ 程序里,每个一般函数只能有一个定义。因为链接器在把多个目标文件组合成可实行程序时,如果发现同一个一般函数存在多个不同定义,就没办法确定该用哪个,进而导致链接错误。例如,有source1.cpp和source2.cpp两个源文件,要是它们都定义了void func() { /* 函数体 */ },毗连时就会堕落。正确做法是在一个源文件里定义func函数,在其他需要使用的源文件里通过声明(void func();)来使用它
翻译单元级别只有一处定义:内联函数、类、模板:翻译单元指的是源文件加上它引用的头文件,并忽略预处置惩罚语句后的内容。内联函数、类和模板在每个翻译单元中都只能有一个定义。这是因为内联函数在编译时会把函数体直接插入到调用处,如果不同翻译单元的定义不同,大概会导致行为不一致;类定义描述了对象的布局和行为,不同翻译单元的类定义不同,对该类对象的使用也会混乱;模板是生成详细函数或类的蓝图,不同翻译单元对同一模板定义不同,生成的实例也会有差异。好比定义了内联函数inline int add(int a, int b) { return a + b; },可以在多个源文件对应的翻译单元中使用,但每个翻译单元里的定义必须一致,通常把它放在头文件中,让包罗该头文件的翻译单元都能使用相同的定义。
编译链接模型的实例