C++面向对象编程(一)
今天看了一点primer中有关面向对象编程的内容,以下是自己的一点总结。
一、关于虚函数
1、定义为virtual的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参类型。以实现统一的接口,不同定义过程。
2、通过基类的引用(或指针)调用虚函数时,发生动态绑定。引用(或指针)既可以指向基类对象也可以指向派生类对象,这一事实是动态绑定的关键。用引用(或指针)调用的虚函数在运行时确定,被调用的函数是引用(或指针)所指对象的实际类型所定义的。
3、继承层次的根类一般都要定义虚析构函数。而构造函数不能被定义为虚函数。
4、要触发动态绑定,必须满足两个条件:第一,只有指定为虚函数的成员函数才能进行动态绑定,第二,必须通过基类类型的引用或指针进行函数调用。每个派生类对象都包含基类部分,所以可将基类类型的引用绑定到派生类对象的基类部分,也可以用指向基类的指针指向派生类对象,任何可以在基类对象上执行的操作也可以通过派生类对象使用。
二、关于访问权限
5、派生类不能访问基类的private成员。
6、派生类只能通过派生类对象访问其基类的protected成员,派生类对其基类类型对象的protected成员没有特殊访问权限。
7、各种继承
*公用继承:基类成员保持自己的访问级别,基类的public成员为派生类的public成员,基类的protected成员为派生类的protected成员。
*受保护继承:类类的public和protected成员在派生类中为protected成员。
*私有继承:基类的所有成员在派生类中为private成员。
8、派生类可以恢复继承成员的访问级别,但不能使访问级别比基类中原来指定的更宽松。
9、可以使用using声明访问基类中的名字,除了在作用域操左边用类名字代替命名空间名字之外,使用形式是相同的。
10、使用class保留字定义的派生类默认具有private继承,而用struct保留字定义的类默认具有public继承。
三、继承中的友元和static
11、友元关系不能继承。基类的友元对从该基类派生的类型没有特殊访问权限。同样,如果类和派生类都需要访问另一个类,那个类必须特地将访问权限授予基类和每一个派生类。简单点来说就是,我朋友的朋友不是我的朋友。
12、如果基类定义了static成员,则整个继承层次中只有一个这样的成员。无论从基类派生出多少个派生类,每个static成员只有一个实例。
四、继承中的转换关系
13、派生类对象也是基类对象,存在从派生类型引用(指针)到基类类型引用(指针)的自动转换,但没有从基类引用(或基类指针)到派生类引用(或派生类指针的)的(自动)转换。也没有从派生类型对象到基类类型对象的直接转换。
14、如果有一个派生类型的对象,则可以使用它的地址对基类类型的指针进行赋值或初始化。可以使用派生类型的引用或对象初始化基类类型的引用,一般可以使用派生类型对象对蕨类对象进行赋值或初始化。
15、引用转换与转换对象。
*将对象付给希望接受引用的函数时,引用直接绑定到该对象,实际上实参是该对象的引用,对象本身未被复制,且该对象仍是派生类型对象。
*将派生类对象付给希望接受基类类型对象(而不是引用)的函数时,情况完全不同。该派生类对象的蕨类部分被复制到形参。
16、基类到派生类的自动转换是不存在的。需要派生类对象时不能使用基类对象。
五、继承中的构造函数和复制控制
17、构造函数和复制控制成员(复制构造函数、赋值操作函数和析构函数)不能继承,每个类定义自己的构造函数和复制控制成员。
18、可将某些类需要只希望派生类使用的特殊构造函数定义为protected;
19、合成的派生类默认构造函数,除了初始化派生类的数据成员之外,它还初始化派生类对象的基类部分。基数部分由基类的默认构造函数初始化。
20、派生类构造函数的初始化列表只能初始化派生类的成员,不能直接初始化继承成员,但可通过将基类包含在构造函数初始化列表中来间接初始化继承成员。
Class B:public A
{
Public”
B():A(1, 0), b(1) {}
Private:
Int b;
};
21、一个类只能初始化自己的直接基类。
22、如果派生类定义了自己的复制构造函数,该复制构造函数一般应显式使用基类复制构造函数初始化对象的基类部分。
23、如果派生类定义了自己的赋值操作符,则该操作符必须对基类部分进行显式赋值。
24、派生类析构函数不负责撤销基类对象的成员。每个析构函数只负责清除自己的成员。要保证运行适当的析构函数,基类中的析构函数必须为虚函数。如果析构函数为虚函数,那么通过指针调用时,运行哪个析构函数将因指针所指对象类型的不同而不同。如果层次中根类的析构函数为虚函数,则派生类析构函数也将是虚函数。
25、在基类构造函数或析构函数中,将派生类对象当作基类类型对象对待。如果在构造函数或析构函数中调用虚函数,则运行的是为构造函数或析构函数自身类型定义的版本。将基类的析构函数定义为虚函数后,当利用delete删除一个指向派生类定义的对象指针时,系统会调用相应的类的析构函数。而不将析构函数定义为虚函数时,只调用基类的析构函数