C++多重继承和基类地址

来源:互联网 发布:韩国真实社会现状 知乎 编辑:程序博客网 时间:2024/06/08 12:49

C++支持多重继承,比如

class Derived : public Base1, public Base2 {

    …

};

 

我们熟知的基类指针强转成继承类指针的用法是这样子的:

base *p1 = … // 实际指向derived object

derived *p2 = (derived *)p1;

或者运行时转换,需要打开编译选项rtti

derived *p2 = dynamic_cast<derived>(p1);

if(p2 != NULL) …

// p2可以调用继承类的方法

 

但是如果有多重继承时这个方法就很危险了! 下面举个例子:    

// define an interfaceclass A {public:    A() {        printf("A created at %lld\n", (long long)this);    }    virtual void theInterface() = 0;    int someData1;};// base classclass B {public:    B() {        printf("B created at %lld\n", (long long)this);    }    int someData2;};class C : public B, public A {public:    C() {        printf("C created at %lld\n", (long long)this);    }    // implement interface in A    virtual void theInterface() override {        printf("Interface is called\n");    }};int main(int argc, const char **argv){    B *obj = new C;//    C *obj = new C;//    A *obj = new C;    A *a = (A *)obj;    a->theInterface();        return 0;}

输出:

B created at 140235107214924

A created at 140235107214912

C created at 140235107214912

Segmentation fault: 11


问题的关键是,继承类有两个基类B和A,它们位于不同的内存地址(上面的例子里特意加了成员变量int someData1;和int someData2;就是为了防止B和A碰巧地址重合。

 

编译器在处理这一行的时候:

B *obj = new C;

会把C的基类B的地址赋给obj,而不是C的地址! 因为B和A没有任何关系,obj当然无法直接访问到A和C的函数了。

 

解决方法:

因为B和C是继承关系,可以通过B得到C的地址,然后就得到A的地址了:

A *a = (C *)obj;

A访问theInterface毫无问题了


原创粉丝点击