ODR

one definition rule

一个模版,类型,函数,对象在一个翻译单元只能有一个定义

在一个程序中(的一个特定scope),一个函数和对象的定义只能有一个,否则链接出错;允许模版,类型和内联函数/变量出现多个相同的定义

类定义中的函数定义是implicitly inline的,可以被include到多个文件中而不违反ODR

类定义外的函数定义不implicitly inline

函数的声明又称prototype

函数默认实参应该在声明时给出

Static members are global variables that live inside the scope region of the class.

先声明后使用

定义是更强的声明

如果只是用来声明指针/引用则可以只声明

任何对类型的使用都需要看到完整定义,而不只是前向声明

变量,函数,命名空间,using,类,模版声明 odr-use需要定义存在 • The value of a variable declaration is read or written • The address of a variable or function declaration is taken • A function is called • An object of a class declaration is used

Most declarations are also definitions, with some exceptions such as • Any declaration with an extern specifier and no initializer • Function declarations without function bodies • Declaration of a class name (“forward declaration”)

TypeMeaningExamples
FundamentalA type built into the core C++ languageint, std::nullptr_t
CompoundA type built from fundamental typesint&, double*, std::string, Fraction
User-definedA class type or enumerated type
(包括标准库定义和实现定义)
(In casual use, typically used to mean program-defined types)
std::string, Fraction
Program-definedA class type or enumerated type
(Excludes those defined in standard library or implementation)
Fraction

变量声明

Type var;

推荐用于有构造函数的默认初始化

有默认构造函数就有这个初始化动作

全局变量,static变量和线程局部变量一定先零初始化

Type var{};

推荐用于默认初始化,以及类的静态成员变量 若有非默认提供的默认构造函数,则对象会先零初始化多了一些开销

值初始化/直接列表初始化

auto var = expr

推荐用于有初值初始化 auto和表达式类型相同,如auto var = Type{…}

Type var{…}

推荐用于类的静态成员变量 直接列表初始化 接受包括explicit的构造函数和转换构造函数,拒绝有损转换,还会优先使用构造器列表的构造函数,还可进行聚合初始化 narrowing conversion只涉及数值类型