12.1 类的定义和声明
1.关于成员函数:
(1)在类内部定义的函数默认为inline函数
(2)将关键字const加在形参表之后,就可以将成员函数声明为常量: double avg_price() const;
const成员函数不能改变其操作的对象的数据成员。const必须同时出现在声明和定义中,否则会引起编译错误。
const对象(或指向const对象的引用)只能调用const成员函数,例如 const Type &aref = a ; int i = aref.func(); 如果func不是const函数,则编译错误。const函数若有返回值,且返回类型为引用类型,则返回的必须是const引用,如果func返回的不是int型或const int&型,则编译错误。
2.类可以定义自己的局部类型名字,以简化代码。局部类型名遵循成员的访问控制,定义为public,则允许用户使用这个名字,对外界可见。
【例子】
class Screen{
public:
typedef std::string::size_type index;
private:
index cursor;
...
}
3.声明与定义
(1)可以声明一个类而不定义它,称为前向声明: class Screen; 在定义之前,Screen是不完全类型。
(2)只有当类定义已经在前面出现过,数据成员才能被指定为该类类型。否则,该类为不完全类型,只能将数据成员定义为该类型的指针类型。
class LinkNode{int value ; LinkNode * next;}; //OK
class LinkNode{int vlaue ; LinkNode next;}; //Error
12.2 隐含的this指针
1.关于this指针:
在普通非const成员函数中,this的类型是const指针,其指向的对象为非const;
在const成员函数中,this的类型是指向const对象的const指针
2.关于mutable成员:可以用mutable修饰成员变量使成员变量在任何方法内都可以修改(包括const成员函数)。
12.3类作用域:
成员函数的形参表和函数体都处于类作用域之中,但是返回类型不一定在类作用域中,所以在定义成员函数时需要用完全限定名作为返回类型。
12.4 构造函数:
1.关于构造函数初始化式
(1)构造函数的执行分两个阶段:a.初始化阶段(执行初始化列表);b.执行构造函数体阶段
(2)如果没有为类成员提供初始化式,则编译器会隐式地使用成员类型的默认构造函数初始化类成员。如果其中存在某个成员的类没有默认构造函数,则
该类的默认构造函数将会失败。
(3)有些成员必须在构造函数初始化列表中进行初始化,例如没有默认构造函数的成员,const成员,以及引用类型的成员 !!!
P.389
(4)因为内置成员不进行隐式初始化,所以对他们进行初始化还是在构造函数体中赋值都无关紧要。
(5)初始化式可以使任意表达式
2. 默认实参与构造函数:
可以通过默认实参将默认构造函数与其他构造函数组合起来,减少代码,例如
class Sales_itme {
public :
Sales_item(const std:string &book = ""): isbn(book) , units_sold(0) { }
}
3.默认构造函数
(1)只有当类一个构造函数都没定义的时候,编译器才会生成默认构造函数(合成的默认构造函数)
(2)合成的默认构造函数中,具有类类型的成员通过各自的默认构造函数进行初始化,内置和复合类型的成员,只有定义在全局作用域中的对象才他们进行初始化(对于内置和复合类型成员,如果不在初始化式中对其进行初始化或者构造函数体内进行赋值,那么对象生成后,它们的值是未知的。应该避免!!!提供一个初始化总是对的)
(3)不定义默认构造函数的后果:
a.该类类型不能用作动态分配数组的元素类型
b.该类类型的静态分配数组必须为每个元素提供初始化式
c.保存该类类型的容器,无法使用只接受容器大小的构造函数,必须使用另外提供元素初始化式的重载版本。
因此,如果定义了其他构造函数,则提供一个默认构造函数总是对的!!!
4.类类型的隐式转换
(1)对于obj.func(ClassA a),如果用TYPE类型的对象b作为参数,则会发生隐式转换,编译器用b作为参数调用ClassA的相应构造函数(如果存在)创建临时对象,传递给func
(2)可以用explicit关键字来抑制构造函数定义的隐式转换,它只能用于类内部的构造函数声明上,在类外的定义体上不再重复它。 通常,单形参构造函数应该声明为explicit,以避免发生错误。
12.5 友元
(1)友元机制允许一个类将对其非公有成员的访问权限授予指定的函数或类,友元的声明以关键字friend开始,只能出现在类定义的内部。如果将一个类声明为友元,那么该类的所有成员函数都能访问它的非公有成员。
class Screen{
friend class Window_Mngr;
friend void func();
friend Window_Mngr::relocate(Window_Mngr::index,Window_Mngr::index,Screen&);
...
}
(2)类必须将重载函数集中每一个希望设为友元的函数都声明为友元,即友元声明只对使用friend关键字的重载版本起作用。
12.6 static类成员
(1)static成员函数只需在类定义体内部使用static关键字,在类外部定义static成员函数时无需再使用static。
(2)static数据成员必须在类定义体的外部定义(正好一次)。不像普通数据成员,static成员不是通过类构造函数进行初始化,而是应该在定义时进行初始化。一个例外是整型const static数据成员,只要初始化式是一个常量表达式,那么整型const static数据成员就可以在类的定义体中进行初始化。
阅读(411) | 评论(0) | 转发(0) |