我有以下结构:
class ElementEx
{
public:
ElementEx() {}
AddChild(ElementEx* element)
{
// some stuff
}
};
class A : ElementEx
{
public:
A() {}
};
class B : ElementEx
{
public:
B() {}
};
template <class T>
class MyNewClass : public T
{
public:
MyNewClass()
{
ElementEx* newElement = new ElementEx();
AddChild(newElement);
}
};
创建MyNewClass对象时,T必须从A或B继承,因此MyNewClass将从ElementEx继承。但在我的例子中,编译器不知道这一点,也无法弄清楚AddChild是什么。如何确保T类是ElementEx的后代?
我在想什么
((ElementEx*)this)->AddChild(newElement);
但这看起来真的很不优雅(并且容易出错,如果错误的类型以T形式输入),我认为必须有更好的方法来做到这一点。
答案 0 :(得分:3)
编译器在这里抱怨,因为它不知道AddChild
在第一次传递期间依赖于T
。 AddChild
可以通过在this->
之前添加呼叫来使T
成为依赖名称,从而在{{1}}已知时将查询延迟到第二次传递。
答案 1 :(得分:2)
只要您满足于父类支持AddChild
接受ElementEx
,您就可以使用正常的编译器错误轻松完成此操作。
在你的代码中修复了一堆错误后(A和B私有继承,你的所有类都有私有构造函数,AddChild
没有返回类型)我能通过添加{{1}使其工作正常调用this->
因为AddChild
是一个从属名称,你可以通过限定类型或添加AddChild
来向编译器指明。如果您不需要对该方法进行虚拟调用,则可以通过调用this->
来强制执行正确的查找。修正后的代码如下。
ElementEx::AddChild
答案 2 :(得分:1)
有几种方法可以很好地完成这项工作,但它们都有使用1.)静态断言的基础。 2)静态评估函数。
Personaly,我会使用(在构造函数中)
static_assert(std::is_base_of<ElementEx,T>::value,"T must derive from ElementEx")
但可能有更好的方法。你的问题的X部分是什么(你想用这个奇怪的继承结构实现什么?)