81.对象在创建的时候由编译器对VPTR指针进行初始化,只有当对象的构造完全结束后VPTR的指向才能最终确定。父类对象的VPTR指向父类虚函数表,子类对象的VPTR指向子类虚函数表,构造函数中调用虚函数无法实现多态。
82.面向对象中的抽象类:
(1)抽象类可用于表现现实世界中的抽象概念。
(2)抽象类是一种只能定义类型,而不能产生对象的类。
(3)抽象类只能被继承并重写相关函数。
(4)抽象类的直接特征是纯虚函数。
纯虚函数是只声明函数原型,而故意不定义函数体的虚函数。
83.抽象类与纯虚函数:
(1)抽象类不能用于定义对象。
(2)抽象类只能用于定义指针和引用。
(3)抽象类中的纯虚函数必须被子类重写。
class Shape
{
public:
virtual double area() = 0;
};
area是纯虚数,=0告诉编译器,这个函数故意只声明不定义。
84.不要将多态应用于数组:
(1)指针运算是通过指针的类型进行的。
(2)多态通过虚函数表实现的。
85.被实际开发经验抛弃的多继承:
(1)工程开发中真正意义上的多继承是几乎不被使用的。
(2)多重继承带来的代码复杂性远多于其带来的便利性。
(3)多重继承对代码维护性上的影响是灾难性的。
(4)在设计方法上,任何多重继承都可以用单继承代替。
86.在只有单继承的系统中,类之间的继承关系为一棵树,在引用多重继承的系统中,类之间的继承关系呈现为一张图。
87.C++中对多继承二义性的解决方案为使用虚继承。虚继承:为了解决从不同途径继承来的同名数据成员造成的二义性问题,可以将共同基类设置为虚基类。这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝。
88.绝大多数面向对象语言都不支持多继承,绝大多数面向对象语言都支持接口的概念,C++没有接口的概念但可以通过使用纯虚函数实现接口:
class Interface
{
public:
virtual void func1() = 0;
virtual void func1(int i) = 0;
virtual void func3(int i, int j) = 0;
};
接口类中只有函数原型定义,没有任何数据的定义。
89.实际工程经验证明:
(1)多重继承接口不会带来二义性和复杂性等问题。
(2)多重继承可以通过精心设计用单继承和接口来代替。
(3)接口类只是一个功能说明,而不能功能实现。子类需要根据功能说明定义功能实现。
90.泛型编程的概念,不考虑具体数据类型的编程模式,对于swap函数可以考虑下面的泛型写法:
void Swap(T & a , T & b)
{
T t = a;
a=b;
b=t;
}
Swap 泛型写法中的T不是一个具体的数据类型,而是泛指任意数据类型。