动态转换和多重继承

发布于 2024-09-16 00:29:10 字数 1265 浏览 4 评论 0原文

当我应用于指向多重继承对象实例的指针时,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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

别念他 2024-09-23 00:29:10

注意:为了简单起见,我在本示例中使用基本指针。实际代码使用 boost::shared_ptr

这就是你的问题:你不能将 shared_ptr 动态转换为 shared_ptr 因为这两种类型实际上并不相关彼此,即使 AB 是。

幸运的是,在您问题的具体情况下, dynamic_cast 应该不是必需的,因为 Record_ID_As_Field* 应该隐式转换为 Field_Interface* (因为一个是从另一个派生出来的)。 shared_ptr 实现转换运算符,将这些隐式转换提升为相应的 shared_ptr 对象,因此 shared_ptr 应隐式转换为 shared_ptr< ;Field_Interface>

如果您省略dynamic_cast,它应该可以工作。

如果您确实需要进行动态转换,则可以使用 shared_ptr 提供的特殊构造函数

shared_ptr<Record_ID_As_Field> raf;
shared_ptr<Field_Interface> fi(raf, dynamic_cast<FieldInterface*>(raf.get());

(我不确定如果 dynamic_cast 失败会发生什么,所以你应该调查一下处理这种情况的最佳方法是什么。)

Note: For simplicity, I am using fundamental pointers in this example. Actual code uses boost::shared_ptr.

And that's your problem right there: You cannot dynamic_cast a shared_ptr<A> to a shared_ptr<B> since those two types are not actually related to each other, even if A and B are.

Luckily in the specific case in your question the dynamic_cast shouldn't be necessary, since Record_ID_As_Field* should be implicitly convertible to a Field_Interface* (since the one is derived from the other). shared_ptr implements conversion operators that lift these implicit conversions to the respective shared_ptr objects, so shared_ptr<Record_ID_As_Field> should be implicitly convertible to shared_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:

shared_ptr<Record_ID_As_Field> raf;
shared_ptr<Field_Interface> fi(raf, dynamic_cast<FieldInterface*>(raf.get());

(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.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文