如果我有这个代码,例如:
class ChildOne
{
ChildOneFunc()
{
Parent::ParentFunction();
}
CallNeighbour()
{
ChildTwoFunc();
}
};
class ChildTwo
{
ChildTwoFunc();
};
class Parent : public virtual ChildOne, public virtual ChildTwo
{
Parent() //Constructor
{
ChildOneFunc();
}
ParentFunction();
};
怎么可能这样做? 因为在Child 2中,Class Parent没有定义和转发声明 只给我错误。
第二个问题:
我如何从Childtwo调用CildOneFunction()?
答案 0 :(得分:0)
您可以通过静态或动态多态实现第一个。避免使用“父”和“孩子”这一令人困惑的命名法,这是使用动态多态的可能性:
tagset = None
tokens = nltk.word_tokenize('the mat sat on the cat')
tags = nltk.tag._pos_tag(tokens, tagset, tagger)
此处,struct base /* aka ChildOne */
{
virtual void func() const = 0;
void basefunc() { func(); }
};
struct derived /* aka Parent */
: base
{
void func() const override;
};
类与derived
的是-a 关系:base
类型的对象也是对象类型derived
。动态多态通过虚拟表实现,这会产生一些(小的)运行时开销。这可以通过CRTP使用静态多态来避免:
base
不需要查找虚拟表,因为没有使用template<typename Derived>
struct base
{
void basefunc() { static_cast<const Derived>(this)->func(); }
};
struct derived
: base<derived>
{
void func() const;
};
函数。
答案 1 :(得分:0)
简短的回答是:一般情况下你不能这样做,但你可以使用dynamic_cast
添加支票。
使用Parent
名称定义派生类,使用Child
定义基类有点令人困惑,但我会使用您的术语。
ChildTwo
类与ChildOne
没有继承关联,因此在ClassTwo
的任何方法中,您只有一个ClassTwo
对象,可能无法实现ChildOne
方法。但您可以使用dynamic_cast
:
ChildTwoFunc()
{
auto thisAsChildOne = dynamic_cast<ChildOne*>(this);
if (thisAsChildOne != nullptr)
{
thisAsChildOne->ChildOneFunc();
}
}
这里我们首先尝试将this
转换为指向ChildOne
的指针,并进行所有必要的运行时检查。如果this
不是ChildOne
派生的任何类的对象(在您的示例中,如果this
不是Parent
),则此dynamic_cast
将返回nullptr
}。如果演员阵容成功,我们会调用该函数。
对于任意ChildTwo
,您可以强制编译器使用reinterpret_cast
调用此函数,但这是 HIGHLY UNSAFE 。
有关dynamic_cast
的详情,请参阅here