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”)
| Type | Meaning | Examples |
|---|---|---|
| Fundamental | A type built into the core C++ language | int, std::nullptr_t |
| Compound | A type built from fundamental types | int&, double*, std::string, Fraction |
| User-defined | A class type or enumerated type (包括标准库定义和实现定义) (In casual use, typically used to mean program-defined types) | std::string, Fraction |
| Program-defined | A 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只涉及数值类型