22、关于静态数据成员初始化:
[cpp]
在CODE上查看代码片派生到我的代码片
class FC{
public:
static int si = 9;//错误
const int si0 = 7;//正确,int有序类型
const static int si1 = 8;//正确,int有序类型
const static char *cs = "abcd";//char* 不是有序类型
int *pi = 0;//错误
double d = 0.0;//错误
};
静态数据成员的类型可以是其所属类,而非static数据成员只能被声明为该类的对象的指针或引用。如:
[cpp]
在CODE上查看代码片派生到我的代码片
class Bar{
private:
static Bar bar;//ok
Bar *pbar;//ok
Bar &rbar;//ok
Bar bar0;//错误
};
23、指向类成员函数的指针:
[cpp]
在CODE上查看代码片派生到我的代码片
#include <iostream>
using namespace std;
int (*fp)();
int (*fpstatic)();
class Screen{
public:
inline int high(){return _high;}
static int statichigh(){return 90;}
private:
int _high;
};
int main(){
fp = &Screen::high;//非法赋值,类型违例
fpstatic = &Screen::statichigh;//静态类型的合法,与普通函数指针相同
}
//非static成员函数的指针必须与其赋值的函数类型匹配在下列三个方面都匹配:
//1)参数的类型和个数;2)返回类型;3)它所属的类类型
//所以fp必须被声明为如下形式,保证fp的类类型为Screen
int (Screen::*fp)();
//才能使用
fp = &Screen::high;
24、联合、位域、类域、嵌套类、局部类有时间看看。
25、类的初始化、构造函数、析构函数相关:
a、显式初始化表:通过显式初始化表,用常量初始化大型数据结构比较有效。例如,我们创建一个调色板,或者向一个程序文本中注入大量的常量值,如一个复杂地理模型中的控制点和节点值。在这种情况下,显式初始化可以在装载时刻完成,从而节省了构造函数的启动开销(即使它被定义为inline),尤其是对全局对象。
[cpp]
在CODE上查看代码片派生到我的代码片
class Data{
public:
int ival;
char *ptr;
};
//Date类需要提供一个构造函数嘛?正如它的定义所示,它不需要,因为它的所有数据成员都是公有的。从C语言继承来的机制支持显示初始化表,类似于用在初始化数组上的初始化表。例如:
int main()
{
//local1.ival = 0; local1.ptr = 0;
Data local1 = {0, 0};
//local2.ival = 1024;local2.ptr = "Look at"
Data local2 = {1024, "Look at"};
}
//根据数据成员被声明的顺序,这些值按位置被解析。例如下面是一个编译错误,因为ival在ptr之前被声明:
Data local3 = {"Look at", 1024};
b、不指定参数来定义对象:只有当没有构造函数或声明了缺省构造函数时,我们才能不指定实参来定义类对象。一旦一个类声明了一个或多个构造函数,类对象就不能被定义为不调用任何构造函数的实例。尤其是,如果声明了一个包含多个参数的构造函数,但没有声明缺省构造函数,则每个类对象定义的时候都必须提供所需的参数。
在实践中,如果定义了其他构造函数,则也有必要提供一个缺省构造函数。如果没有缺省构造函数,下面的语句就是错误的:
Account *pact = new Account[1024];//在new的过程中会调用缺省构造函数,如果Account没有提供缺省构造函数则是错误的。
同样情况,容器类(比如vector)要求他们的类元素或者提供缺省的构造函数,或者不提供构造函数。