我可以教dynamic_cast<>()新技巧吗?

发布于 2024-09-13 18:27:10 字数 810 浏览 9 评论 0 原文

C++ 中有没有一种方法可以构造您的类,以便给定一个指向您的类的指针,您可以指示dynamic_cast<>() 如何转换为您要包装其实现的另一个类?运算符强制转换可以解决问题吗?想象一下,我有一个抽象接口基类,并从中派生出一个creteA和一个concreteB,但是concreteB将该接口包装到一个concreteA类型的对象。如果我收到从creteA转换为concreteA的请求,我希望它能够工作:

class Abstract {
public:
  virtual void interface() = 0;

};

class concreteA : public Abstract {
public:
  virtual void interface();

};

class concreteB : public Abstract {
public:
  concreteB(concreteA &underlying)
    : _underlying(&underlying) {
  }
  virtual void interface();

  operator concreteA*() {
    return _underlying;
  }

private:
  concreteA *_underlying;

};

void
myTest() {
  concreteA myClassA;
  concreteB myClassB(myClassA);
  Abstract *abstract = &myClassB;
  concreteA *underlying = dynamic_cast<concreteA *>(abstract);
}

Is there a way in C++ to construct your class such that given a pointer to your class you can instruct dynamic_cast<>() how to cast to another class for which you are wrapping the implementation? Would operator cast do the trick? Imagine I have an Abstract interface base class and derive a concreteA from this as well as concreteB, but concreteB wraps the interface to an object of type concreteA. If I get a request to cast to concreteA from concreteA, I'd like it to work:

class Abstract {
public:
  virtual void interface() = 0;

};

class concreteA : public Abstract {
public:
  virtual void interface();

};

class concreteB : public Abstract {
public:
  concreteB(concreteA &underlying)
    : _underlying(&underlying) {
  }
  virtual void interface();

  operator concreteA*() {
    return _underlying;
  }

private:
  concreteA *_underlying;

};

void
myTest() {
  concreteA myClassA;
  concreteB myClassB(myClassA);
  Abstract *abstract = &myClassB;
  concreteA *underlying = dynamic_cast<concreteA *>(abstract);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(1

初雪 2024-09-20 18:27:10

不。动态强制转换告诉编译器“我根本不想更改此对象,我只是想尝试将其视为其他类型,但不要更改它。如果必须这样做更改它、返回 NULL 或抛出异常。”。动态转换不会尝试代表您执行任何此类转换。为此,您需要 static_castboost::lexical_cast

这是因为强制转换运算符可以:

  • 以新的方式重新解释现有对象而不更改它
  • 以某种方式更改对象以将其强制为另一种类型,例如 int ->短,或双 ->国际。

并且单个强制转换调用只能执行其中一个,而不是两者。

有关强制转换运算符的“双重”性质的更多信息,您可以参阅 Eric Lippert 的这篇文章,针对 C#,但主要也适用于 C++。

具体来说,您可以在最新的 C++0x 草案中看到第 5.2.7 节——该行为与 C++03 相比没有改变。

No. A dynamic cast is telling the compiler "I don't want to change this object at all, I just want to attempt to look at it as if it were this other type, but don't change it. If you have to change it, return NULL or throw an exception.". Dynamic cast is not going to attempt to perform any such conversions on your behalf. For that, you need static_cast or boost::lexical_cast.

This is because the cast operator can either:

  • Reinterpret an existing object in a new way without changing it
  • Change an object in some way in order to coerce it to be another type, such as int -> short, or double -> int.

and a single cast invocation can only do one of these, not both.

For more information on the "dual" nature of the cast operator, you can see this article by Eric Lippert, which is aimed at C# but mostly applies to C++ as well.

Specifically, you can see § 5.2.7 in the most recent C++0x draft -- that behavior is not changed from C++03.

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