现在的位置: 首页 > 综合 > 正文

C++ Primer(4th) Chapter12

2013年03月30日 ⁄ 综合 ⁄ 共 1532字 ⁄ 字号 评论关闭
文章目录

const成员函数

基于成员函数是否为 const,可以重载一个成员函数;同样的,基于一个指针形参是否指向const,可以重载一个函数。const 对象只能使用 const 成员;非 const 对象可以使用任一成员,但非const版本是一个更好的匹配。

每一个成员函数都有一个隐含的this指针,对于非 const 成员函数,该指针的类型是 T const *;而对于const成员函数,该指针的类型是const T const * 

名字查找

名字查找(寻找与给定的名字使用相匹配的声明的过程)

  1. 首先,在使用该名字的块中查找名字的声明。只考虑在该项使用之前声明的名字。
  2. 如果找不到该名字,则在包围的作用域中查找。
  3. 如果找不到任何声明,则程序出错。

类定义实际上是在两个阶段中处理:

  1. 首先,编译成员声明;
  2. 只有在所有成员出现之后,才编译它们的定义本身。

类成员声明中的名字查找:

  1. 检查出现在名字使用之前的类成员声明;
  2. 如果第一步查找不成功,则检查包含类定义的作用域中出现的声明以及出现在类定义之前的声明。

注意:必须在类中先定义类型名字,才能将它们用作数据成员的类型,或者成员成员函数的返回类型或形参类型。编译器按照成员声明在类中出现的次序来处理它们。通常,名字必须在使用之前进行定义。而且,一旦一个名字被用作类型名,该名字就不能重复定义。

类成员定义中的名字查找:

  1. 首先检查成员函数局部作用域中的声明;
  2. 如果在成员函数中找不到该名字的声明,则检查对所有类成员的声明;
  3. 如果在类中找不到该名字的声明,则检查在此成员函数定义之前的作用域中出现的声明。

 

构造函数初始化列表

从概念上讲,可以认为构造函数分两个阶段执行:

  1. 初始化阶段:对所有数据成员进行初始化。如果在初始化列表中提供了初始化式,则按要求初始化;如果未提供,对于类类型,执行默认构造函数,对于内置类型和复合类型,不初始化。
  2. 普通计算阶段:由构造函数体中的所有语句组成。

有些成员必须在构造函数初始化列表中进行初始化。对于这样的成员,在构造函数函数体中对它们赋值不起作用。没有默认构造函数的类类型的成员、以及const引用类型的成员,不管是哪种类型,都必须在构造函数初始化列表中进行初始化。

对于非类类型的数据成员进行赋值或使用初始化式在结果和性能上都是等价的。

构造函数初始化列表仅指定用于初始化成员的值,并不指定这些初始化执行的次序。成员被初始化的次序就是定义成员的次序。

 

默认构造函数

只有当一个类没有定义构造函数时,编译器才会自动生成一个默认构造函数。合成的默认构造函数使用与变量初始化相同的规则来初始化成员。

在某些情况下,默认构造函数是由编译器隐式应用的。如果类没有默认构造函数,则该类不能用在这些环境中。以下假设NoDefault类没有默认构造函数,这意味着:

  • 具有NoDefault成员的每个类的每个构造函数,必须使用初始化列表显式初始化它;
  • 不能用作动态分配数组的元素类型;
  • 该类型的静态分配数组必须为每个元素提供一个显式的初始化式;
  • 如果有一个保存该类型对象的容器,如vector,就不能使用接受容器大小而没有同时提供一个元素初始化式的构造函数。

 

隐式类类型转换

具有单个形参的构造函数定义了从形参类型到该类类型的一个隐式转换。当构造函数被声明为explicit时,编译器将不使用它作为转换操作符。注意,explicit关键字只能用于类内部的构造函数声明上。

通常,除非有明显的理由想要定义隐式转换,否则,单形参构造函数应该explicit。将构造函数设置为explicit可以避免错误,并且当转换有用时,用户可以显示的构造对象。

显示构造的方法是直接调用构造函数,如T(param)创建一个临时对象,也可以理解为强制类型转换。

任何构造函数都可以用显式调用的方式创建临时对象。

抱歉!评论已关闭.