虚拟函数中的类转换c ++

时间:2018-02-08 13:30:02

标签: c++

您好我有以下代码 -

class A{
public:
    A(){
        cout << "In A CTR" << endl;
       }

    virtual void buildTree() = 0;

    void print(){
    cout << "int A print  This = " << this << endl;
    }
};


class B{
public:
    B(){
        cout << "In B CTR" << endl;
    }
    virtual A* getBuilder() {
        cout << " In B getBuilder , this = " << this << endl;
        return NULL;
    }
    virtual void hell(){
        cout << "In B hell This =" << this << endl;
    }
    void print(){
        cout << "in B print This = " << this << endl;
    }
    B* add(B* child){
        cout << "In B add , This = " << this <<endl;
    }
};

class C : public A, public B{
public:
    C(){
        cout << "In C CTR" << endl;
    }
    A* getBuilder() {
        cout << "In C getBuilder , this = " << this << endl;
        return this;
    }
    void print(){
        cout << "In C print  This = " << this << endl;
    }
};

class D : public C{
public:
    D(){
        cout <<"In D CTR" << endl;
    }
    void buildTree(){
        cout << "buildTree in D , This = "  << this << endl;
        B *b = NULL;
        add(b);
    }
    void print(){
        cout << "In D print  This = " << this << endl;
    }
};

int main() {
 B *root = new D();
 root->getBuilder()->buildTree();
 return 0;
}

我得到以下输出:

在C getBuilder中,this = 0x7f9aa0500100

在D中的buildTree,this = 0x7f9aa0500100

在B中添加this = 0x7f9aa0500108

我无法弄清楚为什么调用add()中的class B。这是我的理解。请纠正我。

rootB类型的指针,指向D。 因此,当调用root->getBuilder()时,它会调用class C中的虚函数,该函数返回类型为A*的指针。

所以,现在root->getBuilder()返回一个指向D的A类指针。 因此root->getBuilder()->buildTree()能够在D中调用buildTree。

但是在class D中的buildTree中,我们调用了class B中定义的add。 我们如何调用它,因为指针类型为A且对B函数不了解。

感谢任何帮助。

由于

2 个答案:

答案 0 :(得分:1)

这似乎是个问题:

  

但是在D类的buildTree中,我们调用了已定义的add   在B类中,我们如何调用它,因为指针类型是A.   并且不应该对B,函数一无所知。

在指针类型buildTree上调用A*,其中buildTree被标记为虚拟,将在D*给定root上调用buildTree类型D。因此add可以使用D,因为D可以访问公共,受保护的方法是超类。

原始代码示例不必要地复杂化。可以通过以下代码检查相同的原理:

A *root = new D();
root->buildTree();

答案 1 :(得分:1)

你拥有的基本上是这个(非常简化):

struct B
{
    B* add(B*)
    {
        std::cout << "B::add\n";
    }
};

struct C : B
{
    // Nothing relevant
};

struct D : C
{
    void buildTree()
    {
        add(NULL);
    }
};

int main()
{
    D root;
    root.buildTree();
}

班级D C。课程C B。这意味着D 也是 B。因此D具有成员函数add

如果您可以从add成员函数调用D,则指针和间接是红色鲱鱼。

我认为我现在看到了问题,而且是关于班级向全世界展示的界面。

再次使用基本和简化的示例:

struct A
{
    void funA();
}

struct B
{
    // Nothing relevant
};

struct C : A, B
{
    // Nothing relevant
};

然后通过

B* p = new C;

有效。但即使指针p指向C的对象(也是A),它也没有A接口 (或C),只有B

如果您想使用AC中的功能,则必须使用向下投射将其转换为正确的类型:

static_cast<D*>(p)->funA();  // Cast to the type `p` *really* is