多重继承:代码复用,一个派生类有多个基类。如:class C: public A,public B{};
10年积累的成都网站建设、网站建设经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站设计后付款的网站建设流程,更有丰泽免费网站建设让你可以放心的选择与我们合作。
虚基类:virtual可以修饰继承方式,是虚继承,被虚继承的类,称作虚基类。class A:virtual public B{};
虚继承的类中会多一个vbptr指向vbtable,Vbtable中保存的是虚基类中数据在派生类中的内存偏移量,从虚基类中继承的成员变量会被放在派生类内存的最下端。
虚函数和虚基类在调用的时候是没有问题的,
但是在delete的时候会发生堆报错
原因是:基类指针类型的成员p指向派生类对象,永远指向的是派生类基类部分数据的起始地址,这里的基类A的起始位置就是vfptr。但是这里的派生类B是虚继承的A,虚继承的部分会放到派生类内存的后面,p指向的就是派生类后面的内存,这种情况Delete p就不会删除派生类中的内存,造成了上图中的问题。
class A{
public:
virtual void func(){cout<<"call A:func"<func();
delete p;
}
delete的内存地址与new的内存地址不同,所以会造成问题。
继承的样子像菱形,叫菱形继承。类D中会继承两个类A中的成员。尽量避开多重继承。
多重继承的好处:可以做更多代码的复用。
用虚继承解决上面的问题。
class A{
public:
A(int data):ma(data){
cout<<"A()"<
如果虚继承就会在B和C中构造出vbptr指针,在D中指向类A中的成员变量。
使用虚继承避免继承多次的问题:
class B:virtual public A{//使用虚继承避免菱形继承的问题
public:
B(int data):A(data),mb(data){
cout<<"B()"<
const_cast
:去掉(指针或者引用)常量属性的一个类型转换
static_cast
:提供编译器认为安全的类型转换 基类和派生类可以通过static_cast进行转换
reinterpret_cast
:类似于c风格的强制类型转换(不安全)
dynamic_cast
:主要用在继承结构中,可以支持RTTI类型识别的上下转换
解释一下dynamic_cast的用法:
class Base{
public:
virtual void func()=0;
};
class Derive1:public Base{
public:
void func() override {
cout<<"Derive1::func()"< (p);
if(dp2!= nullptr){
dp2->funcDerive2();
}else
p->func();
}
int main(){
Derive1 d1;
Derive2 d2;
show(&d1);
show(&d2);
return 0;
}
/*
输出结果:
Derive1::func()
Derive2::funcDerive2()*/