第5章 隐藏实现
1. 设置限定
Cstruct无法控制客户程序员进行特殊的行为,无法控制客户程序员操作struct里的函数
2. C++访问权限控制
public成员:任何人都可以访问。类似于struct。
private成员:只有自己可以访问,任何人都不可以访问,private是设计者与客户程序员之间的一堵墙。只有成员函数才可以访问,全局函数不可以访问。
protected:只有继承的子类才可以访问,但不能访问private成员。
3. 友元
1) 如何使非当前类的成员函数显示的获得访问权限?通过声明友元即可。
2) 友元声明必须出现在结构声明中;
3) 一条很重要的规则是:谁可以访问我的私有成员。
4) 注:
Ø 友元函数不是类的成员函数
Ø 使用友元目的是提高程序的运行效率
Ø 慎用友元函数。
5) 嵌套友元:首先声明(不定义)一个嵌套结构,然后声明它是全局范围内的一个friend;最后定义。
class Holder {
public:
class Pointer;
friend Pointer;
class Pointer {
///definition
};
};
第6章 初始化和清除
1. 构造函数
class X {
int i;
public:
X();
};
void f()
{
X a;
}
l 构造函数在对象初始化时自动被调用。
l 传递到构造函数的第一个参数是this指针,也就是调用这一函数对象的地址,不过对构造函数而言,this指针指向一个没有被初始化的内存块,构造函数的作用是正确的初始化该内存块。
l 可以向构造函数传递参数。
l 构造函数和析构函数都没有返回值。
2. 析构函数
l 当对象超出它的作用域时,编译器将自动调用析构函数
3. 清除定义块
l 一般来说,应该尽可能在靠近变量使用点处定义变量,并在定义时初始化:?
这样做可以减少变量在块中的生命周期,减少变量在块的其他地方被误用的机会。增强可读性。
l 局部变量可以屏蔽其封闭块内的其他同名变量。
l 内存分配:一般地,编译器会在程序块开头就分配所有内存,然而即使存储空间在块的一开始就被分配,构造函数也仍然要到对象定义时才会被调用。编译器会检查有没有把对象定义在(构造函数的调用)放到一个条件块中。比如switch。编译器会报错。
void f(int i) {
switch(i) {
case 1 :
X x2; // Constructor called here
break;
case 2 : // Error: case bypasses init
X x3; // Constructor called here
break;
}
}
这里g++编译器报错:
Nojump.cpp:27:7: error: jump to case label [-fpermissive]
Nojump.cpp:25:9: error: crosses initialization of 'X x2'
4. 聚合初始化
l 数组
int b[5] = {1};
编译器会把第一个初始化值赋给数组的第一个元素,然后0赋给其余的元素。
b[5] = {1, 0, 0, 0, 0};
l struct、class
struct X {
int i;
float f;
char c;
};
X x[3] = { {1, 2.2, 'c'}, {2, 3.2, 'd'}};
但是!当出现如下情况,只能调用构造函数了,对数组中每个对象都调用了构造函数。可以直接指定:这里对象X[3]被初始化为0;
struct X {
int i;
float f;
X(int a);
};
X x[3] = { X(1), X(2), X(3)};