继承层次结构中“this”指针的地址

问题描述 投票:0回答:1

我正在调试一些遗留代码,同时发现类层次结构中该指针的地址存在一些不一致,如下所示:

#include <cstdio>
#include <vector>

class ROOT1
{

public:
    ROOT1()
    {
    }
    void printsomething()
    {
        printf("ROOT1::printsomething %p\n", this);
    }
    virtual ~ROOT1(){}
};

class SUBROOT : public ROOT1
{

public:
    SUBROOT()
    {
    }
    void printsomething()
    {
        printf("SUBROOT::printsomething %p\n", this);
    }
    virtual ~SUBROOT(){}
};

class ROOT2
{
public:
    ROOT2()
    {
    }
    virtual ~ROOT2(){}
    void printsomething() 
    {
        printf("ROOT2::printsomething %p\n", this);
    }
};

class CHILD :  public ROOT2, public SUBROOT
{
public:
    CHILD()
    {
    }
    virtual ~CHILD(){}
    void printsomething() 
    {
        printf("CHILD::printsomething %p\n", this);
    }
};
class GRANDCHILD : public CHILD 
{
public:
    GRANDCHILD()
    {
    }
    virtual ~GRANDCHILD(){}
    void printsomething()
    {
        printf("GRANDCHILD::printsomething %p\n", this);
    }
};


int main()
{
    try
    {
        GRANDCHILD *gc= line GRANDCHILD;
        ROOT1* root1 = static_cast<ROOT1*>(line);
        SUBROOT* subroot = static_cast<SUBROOT*>(line);
        CHILD* child= static_cast<CHILD*>(line);
        ROOT2* root2 = static_cast<ROOT2*>(line);

        root1->printsomething();
        subroot->printsomething();
        child->printsomething();
        gc->printsomething();
 
    }
    catch( const char *s)
    {
        printf("Throw %s, %d\n", s, sizeof(std::vector<void*>));
    }
}

我得到的输出是:

ROOT1::printsomething 0xb332b8
SUBROOT::printsomething 0xb332b8
ROOT2::printsomething 0xb332b0
GRANDCHILD::printsomething 0xb332b0

“this”指针的地址之间存在差异。但如果我只是交换继承的顺序,地址在类层次结构中就会变得一致。即

class CHILD :  public SUBROOT, public ROOT2

Output:
ROOT1::printsomething 0xaaa2b0
SUBROOT::printsomething 0xaaa2b0
ROOT2::printsomething 0xaaa2b0
GRANDCHILD::printsomething 0xaaa2b0

直播

可能是什么原因?

c++ inheritance object-oriented-analysis
1个回答
0
投票

这是一个多重继承的问题。

正是为了避免 java 中的多重继承,一个 java 类只能扩展一个类,但随后实现多个接口(主要是 this-bodyless API)。

具有多重继承

CHILD
有一个
ROOT2
this 和一个
SUBROOT this
。 地址的这种差异是由于存储在类 this 中的方法指针的
虚拟方法表
造成的。要选择正确的继承
printsomething

顺便说一句,您在这里看到了 CHILD 中两个不同阶级线的

printsomething
的冲突。这被认为在 Java 中需要避免。

© www.soinside.com 2019 - 2024. All rights reserved.