七、C++继承与多态-多重继承的那些坑该怎么填

理解虚基类和虚继承

多重继承:代码复用,一个派生类有多个基类。如: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()"<

C++的四种类型转换

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()*/


文章名称:七、C++继承与多态-多重继承的那些坑该怎么填
本文链接:http://scyanting.com/article/dsoipeo.html