如何从父级转换为chlid类的接口

时间:2016-09-21 07:45:05

标签: c++ interface casting polymorphism multiple-inheritance

假设我有一个父类Parent和子类Child1Child2,后者实现MyInterface

class Parent {
    public:
        Parent();
        virtual ~Parent();
        virtual void MyMethod();
}
class MyInterface {
    public:
        virtual ~MyInterface() {}
        virtual void MyInterfaceMethod() = 0;
}
class Child1 : public Parent {
    public:
        Child1();
        virtual ~Child1();
}
class Child2 : public Parent, MyInterface {
    public:
        Child2();
        virtual ~Child2();
        virtual void MyInterfaceMethod() override;
}

并说我给了Parent*指针,我想检查对象是否正在实现MyInterface,如果是,则将其转换为MyInterface*

我试图通过这种方式实现目标:

void MyFunction(Parent* p) {
    MyInterface* i = dynamic_cast<MyInterface*>(p);
    if (i != 0)
        DoSomething();
    else
        cout << "Cannot do anything.";
}

但我总是等于0表示它永远不会被转换为类型MyInterface*,即使我确定该对象具有良好的类型。

我该如何实现这个目标?

3 个答案:

答案 0 :(得分:2)

Child2 private继承自MyInterface,除非MyFunction()有权访问private基础子对象,dynamic_cast将始终失败。

由于MyInterface似乎是接口,我认为您希望public继承。

class Child2 : public Parent, public MyInterface { }
//                            ~~~~~~      

LIVE(已修正其他错误)

答案 1 :(得分:1)

您的类必须是多态类型才能使dynamic_cast正常工作。

实现这一目标的最简单方法是添加

virtual ~Parent() = default;

位于public类的Parent区域。然后dynamic_cast将嗅探你的界面的继承树,就像一只松鸡一样。

答案 2 :(得分:0)

或者,我们可以使用Visitor Pattern

,而不是使用dynamic_cast
#include <iostream>

class MyInterface {
public:
    virtual void DoSomething() = 0;
};

class Parent {
public:
    virtual ~Parent() = default;
    virtual void accept(class Visitor& visitor) = 0;
};

class Child1 : public Parent {
public:
    virtual void accept(Visitor& visitor);
};

class Child2 : public Parent, public MyInterface {
public:
    virtual void accept(Visitor& visitor);
    virtual void DoSomething();
};

class Visitor
{
public:
    void visit(Child1& child);
    void visit(Child2& child);
};

void Child1::accept(Visitor& visitor) { visitor.visit(*this); }
void Child2::accept(Visitor& visitor) { visitor.visit(*this); }
void Child2::DoSomething() { std::cout << "Do something.\n"; }

void Visitor::visit(Child1& child) { std::cout << "Cannot do anything.\n"; }
void Visitor::visit(Child2& child) { child.DoSomething(); }

void MyFunction(Parent& p) {
    Visitor v;
    p.accept(v);
}

int main()
{
    Child1 c1;
    Child2 c2;
    MyFunction(c1);
    MyFunction(c2);
}

输出:

Cannot do anything.

Do something.