类的作用域、构造函数、静态成员

来源:互联网 发布:μtorrent mac 编辑:程序博客网 时间:2024/05/02 05:06

类的作用域(7.4)

作用域和定义在类外部的成员
当类的成员函数定义在类的外部时(ps:定义在内部为隐藏的 inline 函数, 反之为普通成员函数),若成员函数返回值类型为类中定义的类型,则该返回值类型必须指明它是哪个类的成员。
例:X::Type X::fun(…);

名字查找与类的作用域
成员函数中使用的名字的解析方式:
首先,在成员函数内查找该名字的声明,和普通函数一样,只有在该函数内使用该名字之前的声明才有效;
如果在成员函数内没有找到该名字的声明,则在类内继续查找,类的所有成员都在查找范围之内;
如果类内也没有找到,则在成员函数定义(非声明)之前的作用域内继续查找。

构造函数(7.5)

构造函数初始化列表**
成员变量的初始化,或者通过构造函数的初始化列表,或者执行默认初始化(例如,定义int i ,若构造函数未显示的通过初始化列表初始化i,则执行默认初始化为0);但是,对于const、引用、或者某种未提供默认构造函数的类类型,必须通过构造函数的初始化列表位这些成员提供初值。
成员初始化顺序按照它们在类中定义的顺序,尽量避免使用某些成员变量初始化其他成员变量。
默认构造函数还可以通过提供默认实参是构造函数实现。
(ps: 若定义了自己的构造函数,则程序不再自动产生默认构造函数,必须手动添加)

委托构造函数
即构造函数可以调用其他构造函数。
例: class X{
X(string s, int j){item1= s; item2 = j}
X(): X(“”,0) {}
X(int i): X(“”, i) {}

隐式的类类型转换
只有一个实参的构造函数能够用于执行隐式转换。
例: 上面的构造函数X(int i),则仅一个int 类型的变量就可以转化为X类类型,即可以自动将该int类型变量作为构造函数参数用于构造一个临时X类类型的变量。但是,该类类型转换只允许一步转换, 若将”asd”直接作为构造函数参数则不能实现隐式转换,因为”asd” 首先要转换为string, 而后再转化为X类类型,转换失败。
关键字explicit 可以抑制构造函数定义的隐式转换。此时,为了使用隐式转换, 可以显示构造X类类型的变量,或者使用static_cast使用explicit 构造函数。

聚合类
聚合类要求:
所有成员都是public;
没有任何定义的构造函数;
没有类内初始值;
没有基类,没有virtual 函数。

聚类可以通过一个花括号括起来的成员初始值列表来初始化类内数据成员,初始值的顺序必须与数据成员的声明顺序一致。若初始值列表中元素个数少于数据成员个数,则靠后的数据成员被值初始化。

字面值常量类
字面值常量要求:
数据成员都必须是字面值常量;
类必须至少含有一个constexpr构造函数;
若类内数据成员含有类内初始值,则内置类型成员的初始值必须是一条常量表达式,或者若成员属于某种类类型,则初始值必须使用成员自己的constexpr构造函数;
类必须使用析构函数的默认定义。

另外, constexpr构造函数函数体一般是空的,因为构造函数无返回值,而constexpr函数唯一可执行语句就是返回语句。

类的静态成员

静态数据成员的类型可以是常量,引用,指针,类类型。
类的静态数据成员存在于任何对象之外,静态成员函数也不与任何对象绑定在一起,它们不包含this指针,且静态成员函数也不能声明为const的。
可以使用类作用域运算符直接访问静态成员,同时也可以通过类的对象、引用、指针来访问。
普通静态成员都必须在类的外部进行定义和初始化,且静态数据成员只能定义一次。此外,常量静态数据成员可以在类的内部初始化,但是通常也要在类的外部重新定义该成员(不可修改)。

0 0