继承
单继承:
class <派生类名>:<继承方式><基类名>{
派生类定义新成员
};
-
基类成员在派生类中的访问属性
公有继承:
派生的对象只能基类的public;
派生类的成员函数可以访问基类的public和protected。
私有继承:
派生类的内部成员函数可以访问基类的public、protected
保护继承:
派生类的成员函数和友元可以访问public、protected -
继承时导致的二义性
2.1 类间的转换
a 在公有继承方式时,派生类可以给基类赋值(隐式转换),基类不能给派生类赋值。
b 基类对象可以强制转换为派生类对象指针/引用
c 一个指向基类的指针可以用来指向该基类公用派生类的任何对象(多态性的关键)。
2.2 多基继承
2.3 菱形继承 -
转换构造函数
-
类型转换函数
注意:
a)转换函数必须时成员函数,不能是友元函数
b)转换函数不能指定返回函数,但在函数体内必须用return语句以传值方式返回一个目标类型的变量
c)转换函数不能有参数
非c++内建别A和B,在一下几种情况B能隐式转化为A:
a)B公有继承自A,可以间接继承。
class B:public A{
};
b)B中类型转换函数
class B{
operator A();
};
A a;
B b;
a=b;//合法
c)A实现了非explicit的参数为B(可以有其他带默认值的参数)的构造函数
class A{
A(const B&);
};
A a;
B b;
a=b;//合法
虚函数多态
多态:静态多态性(函数重载、运算符多载)
动态多态性(虚函数)
- 静态联编与动态联编
c++中的函数调用默认不使用动态绑定。要触发动态绑定,需要满足两个条件:
a)只有指定为虚函数的成员函数才能进行动态绑定,成员函数默认为非虚函数,非虚函数不进行动态绑定
b)必须通过基类类型的引用或指针进行函数调用 - 虚函数表指针(vptr)及虚基类表指针(bptr)
c++在布局以及存取时间上主要的额外负担是由virtual引起的。
2.1 虚函数表指针
2.2 含静态变量、虚函数的类的空间计算
2.3 虚函数表的实现
2.4虚基类表指针(bptr) - 虚拟继承时构造函数的书写
- 纯虚函数
class <类名>{
virtual <类型><函数名>(<参数表>)=0;
……
}
**凡是含有纯虚函数的类都称为抽象类,不可以声明对象。**除非派生类中完全实现基类所有的纯虚函数,否则派生类也是抽象类。只定义了protected型构造函数的类也是抽象类。
动态运行时类型识别与显示转换
-
typeid
通过运行时类型识别(RTTI),程序能够使用基类的指针或引用来检索这些指针或引用所指对象的实际类型。
下面两个操作符提高RTTI:
a)typeid 操作符,返回指针或引用所指对象的实际类型
b)dynamic_cast 操作符,将基类类型的指针或引用安全的转换为派生类的指针或引用 -
显示转换
static_cast dynamic_cast const_cast reinterpret_cast
reinterpret_cast
int *ip;
char *pc=reinterpret_cast<char*>(ip);
const_cast 只有使用const_cast才能将const性质去掉
const char *ip;
char *pc=const_cast<char*>(ip);
static_cast 隐式转换
double d=90.0;
int i=d;
//等价于 int i=static_cast<int>d;
类层次间下行转换(把基类指针或引用转换成子类指针或引用)、指针不可以用隐式转换。
dynamic_cast
该运算符把expression转换成type类型的对象。type必须是类的指针、类的引用或者是void*。dynamic_cast 涉及运行时类型检查