一、下标操作符
A a (...);
cout << a[3] << endl;
cout << a.operator[] (3) << endl;
cout << a["张飞"] << endl;
cout << a.operator[] ("张飞") << endl;
二、函数运算符
如果为一个类定义了形如“operator()”的运算符,那么该类的对象就可以当做函数用,该函数的参数表和返回类型就是operator()运算符函数的的参数表和返回类型。
三、解引用(*)和间接访问(->)运算符
class PA {
public:
PA (A* pa) : m_pa (pa) {}
~PA (void) { delete m_pa; }
private:
A* m_pa;
};
void foo (void) {
PA pa (new A (...));
...
}
智能指针:auto_ptr
四、类型转换运算符
五、new/delete运算符
六、不能重载的运算符
:: - 作用域限定
. - 直接成员访问
.* - 成员指针直接解引用
?: - 三目
sizeof - 字节数,sizeof (a = 5)
typeid - 类型信息
七、继承的基本概念和语法
人类:姓名、吃饭
学生是人:学号、学习
教师是人:工资、授课
人类 - 基类(父类)- 姓名、吃饭
/ \ 继承 ^V 派生
学生 教师 - 子类(派生类)
| |
学号、学习 工资、授课
继承表语法:
class 子类 : 继承方式1 基类1, 继承方式2 基类2, ... { ... };
继承方式:公有(public)、私有(private)、保护(protected)
八、继承的基本性质
1.基类中的一切都为子类所继承,就如同是子类的一样。
2.基类的私有部分虽然存在于子类中,但不能为子类直接访问。基类的保护部分可以为子类直接访问。
3.任何时候将子类对象的地址赋值给基类类型的指针都是安全的,反之存在风险。
九、继承方式对访控属性的影响
1.访控属性
访控属性 访控属性 基类 子类 外部 友元
限定符
public 公有 OK OK OK OK
protected 保护 OK OK NO OK
private 私有 OK NO NO OK
2.继承方式
当试图通过一个子类对象访问该对象从其基类继承的成员时,才需要考虑继承方式对访控属性的影响。
A->B->C
B中访问A的成员:不需要考虑B从A的继承方式
C中访问A的成员:需要考虑B从A的继承方式
main中
B b;
通过b访问A的成员:需要考虑B从A的继承方式
基类中的 公有子类 保护子类 私有子类
----------------------------------
公有成员 公有成员 保护成员 私有成员
保护成员 保护成员 保护成员 私有成员
私有成员 私有成员 私有成员 私有成员
表示IsA的关系,一般使用公有继承。
学生是人
教师是人
私用继承,实现继承,仅仅将基类作为子类的实现工具,同时又不希望基类的公有接口通过子类被扩散。保护继承允许基类的公有接口在子类中扩散,但是不能对外部扩散。
class DCT {
public:
void codec (void) { ... };
};
class Jpeg : protected DCT {
public:
void render (void) {
...
m_dct.codec ();
...
}
protected;
DCT m_dct;
};
class Jpeg2000 : public Jpeg {
public:
void render (void) {
...
codec ();
...
}
};
Jpeg jpeg;
jpeg.code (); // ERROR !
十、子类的构造和析构
1.如果在子类的构造函数的初始化表中没有显式地指明基类部分如何初始化,那么系统就以以无参的方式初始化子类对象中的基类子对象,前提是基类类型支持无参构造。否则,就根据所指定的构造函数和参数对基类部分进行初始化。
2.构造和析构顺序
构造:基类->成员->子类
析构:子类->成员->基类
如果有多个成员,则按照其在类中被声明的顺序依次构造,如果有多个基类,则按照继承表的顺序依次构造,析构的顺序与构造严格相反。
3.子类的析构函数(无论自定义还是缺省),都会自动调用基类的析构函数,但是基类的析构函数不会调用子类的析构函数。因此,delete一个指向子类对象的基类指针,将可能引发内存泄漏。
十一、子类的拷贝构造和拷贝赋值
子类的拷贝构造和拷贝赋值需要兼顾子类对象中基类子对象的拷贝,否则该子对象将被已无参方式构造,或者无法得到拷贝源的内容。
十二、名字隐藏
在子类中可以定义和基类同名的标识符,将后者隐藏起来。可以通过作用域限定解隐藏。