动态转换和多重继承
当我应用于指向多重继承对象实例的指针时,dynamic_cast
运算符返回零 (0)。我不明白为什么。
层次结构:
class Field_Interface
{
public:
virtual const std::string get_field_name(void) const = 0; // Just to make the class abstract.
};
class Record_ID_Interface
{
public:
virtual bool has_valid_id(void) const = 0;
};
class Record_ID_As_Field
: public Field_Interface,
public Record_ID_Interface
{
// This class behaves as a Field and a Record_ID.
// ...
}
// A demonstration function
void Print_Field_Name(const Field_Interface * p_field)
{
if (p_field)
{
cout << p_field->get_field_name() << endl;
}
return;
}
// A main function for demonstration
int main(void)
{
Record_ID_As_Field * p_record_id = 0;
p_record_id = new Record_ID_As_Field;
if (p_record_id)
{
// (1) This is the trouble line
Print_Field_Name(dynamic_cast<Field_Interface *>(p_record_id));
}
return 0;
}
我希望将 Record_ID_As_Field
视为 Field_Interface
,但也适合需要 Record_ID_Interface
的地方。
为什么上面 (1) 中的 dynamic_cast
返回 0,如何解决这个问题?
我在 Windows XP 上使用 Visual Studion 2008。
注意:为了简单起见,我在本示例中使用基本指针。实际代码使用 boost::shared_ptr
。
The dynamic_cast
operator is returning zero (0) when I apply to a pointer that points to an instance of a multiply inherited object. I don't understand why.
The hierarchy:
class Field_Interface
{
public:
virtual const std::string get_field_name(void) const = 0; // Just to make the class abstract.
};
class Record_ID_Interface
{
public:
virtual bool has_valid_id(void) const = 0;
};
class Record_ID_As_Field
: public Field_Interface,
public Record_ID_Interface
{
// This class behaves as a Field and a Record_ID.
// ...
}
// A demonstration function
void Print_Field_Name(const Field_Interface * p_field)
{
if (p_field)
{
cout << p_field->get_field_name() << endl;
}
return;
}
// A main function for demonstration
int main(void)
{
Record_ID_As_Field * p_record_id = 0;
p_record_id = new Record_ID_As_Field;
if (p_record_id)
{
// (1) This is the trouble line
Print_Field_Name(dynamic_cast<Field_Interface *>(p_record_id));
}
return 0;
}
I want to have the Record_ID_As_Field
to be treated as a Field_Interface
, but also fit in where Record_ID_Interface
are required.
Why is dynamic_cast
in (1) above returning 0, and how do I resolve this?
I am using Visual Studion 2008 on Windows XP.
Note: For simplicity, I am using fundamental pointers in this example. Actual code uses boost::shared_ptr
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这就是你的问题:你不能将
shared_ptr
动态转换为shared_ptr
因为这两种类型实际上并不相关彼此,即使A
和B
是。幸运的是,在您问题的具体情况下,
dynamic_cast
应该不是必需的,因为Record_ID_As_Field*
应该隐式转换为Field_Interface*
(因为一个是从另一个派生出来的)。shared_ptr
实现转换运算符,将这些隐式转换提升为相应的shared_ptr
对象,因此shared_ptr
应隐式转换为shared_ptr< ;Field_Interface>
。如果您省略
dynamic_cast
,它应该可以工作。如果您确实需要进行动态转换,则可以使用 由
shared_ptr
提供的特殊构造函数:(我不确定如果
dynamic_cast
失败会发生什么,所以你应该调查一下处理这种情况的最佳方法是什么。)And that's your problem right there: You cannot
dynamic_cast
ashared_ptr<A>
to ashared_ptr<B>
since those two types are not actually related to each other, even ifA
andB
are.Luckily in the specific case in your question the
dynamic_cast
shouldn't be necessary, sinceRecord_ID_As_Field*
should be implicitly convertible to aField_Interface*
(since the one is derived from the other).shared_ptr
implements conversion operators that lift these implicit conversions to the respectiveshared_ptr
objects, soshared_ptr<Record_ID_As_Field>
should be implicitly convertible toshared_ptr<Field_Interface>
.If you leave out the
dynamic_cast
, it should work.If you'd actually need to do a dynamic cast, you could use a special constructor provided by
shared_ptr
:(I'm not sure what would happen there if the
dynamic_cast
fails, so you should investigate what's the best way to handle that situation.)