这个问题是关于在具有不同返回类型的派生类中重写虚方法。 对于以下代码:
class father {
public:
virtual father* ref() { return this; }
};
class child : public father {
virtual child* ref() { return this; }
};
当我尝试直接获取指针时,g++ (F15, g++4.5) 报告“父子转换无效”
child m_child;
father* pf = &m_child;
child* pc = pf->ref();
我知道使用了子类中的 ref() 方法,这可能只是编译时类型不匹配。
但是,有什么办法可以不显式地使用类型转换吗?
额外说明: 我了解编译器报告此错误的原因。我需要的是开箱即用的东西,无需显式转换指针即可访问派生对象中的数据。
父类用于将不同的派生子对象放入列表或 vector 中,因此当从列表或 vector 中获取一个项目时,无法判断它属于哪个子类。
我有内部方法来记录和检查子类类型。但我不想显式转换指针。
例如,我想做这样的事情:
// assuming pf is pointer pointed to an item fetch from a vector
switch(fp->get_type()) {
case child_type1: fp->ref()->list1.push(data); break;
case child_type2: fp->ref()->list2.push(data); break;
case child_type3: fp->ref()->list3.push(data); break;
}
现在,我需要在每种情况下显式声明一个新变量或将 fp 显式转换为正确的类型,每次我需要访问派生类中的数据时,这既乏味又令人困惑。
我期望的是:可能一些 boost 库可以用我还不知道的另一种方式做类似的事情,或者 c++11 标准允许它但需要设置一个特殊的编译参数?
最佳答案
简单的回答是“不”。
您丢失了关于 child*
的额外信息( father*
而不是 ref
)当你扔掉m_child
s 类型信息,通过将其存储为指向基 (pf
) 的指针。
如果没有 Actor 就永远不可能的一个原因是这个例子:
class father {
public:
virtual father* ref() { return this; }
};
class childA : public father {
virtual childA* ref() { return this; }
};
class childB : public father {
virtual childB* ref() { return this; }
};
void should_never_compile(int i)
{
childA a;
childB b;
father pf;
if( i ) { pf=&a; }
else { pf=&b; }
// This is evil and will not compile
childA * pa = pf->ref();
//But this is OK:
childA * pa = dynamic_cast<childA*>(pf->ref() );
}
如果你真的想在没有动态转换的情况下实现这一点,你可以只隐藏动态转换(但这让我有点害怕)
class father {
public:
virtual father* ref() { return this; }
template<typename T> T* as() { return dynamic_cast<T*>(ref()); }
};
child m_child;
father* pf = &m_child;
child* pc = pf->as<child>();
关于c++ - 重写虚方法时无法返回派生类指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10011886/