假设我有一个父类Parent
和子类Child1
和Child2
,后者实现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*
,即使我确定该对象具有良好的类型。
我该如何实现这个目标?
答案 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.