加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

使用`dynamic_cast`时,c底漆是否有问题?

发布时间:2020-12-16 10:37:48 所属栏目:百科 来源:网络整理
导读:引自C Primer 5th 19.2.1. dynamic_cast运算符 A dynamic_cast has the following form: dynamic_casttype*(e)dynamic_casttype(e)dynamic_casttype(e) where type must be a class type and (ordinarily) names a class that has virtual functions. In the
引自C Primer 5th 19.2.1. dynamic_cast运算符

A dynamic_cast has the following form:

dynamic_cast<type*>(e)
dynamic_cast<type&>(e)
dynamic_cast<type&&>(e)

where type must be a class type and (ordinarily) names a class that has virtual
functions. In the first case,e must be a valid pointer (§ 2.3.2,p. 52); in the second,e
must be an lvalue; and in the third,e must not be an lvalue.

In all cases,the type of e must be either a class type that is publicly derived from
the target type,a public base class of the target type,or the same as the target
type. If e has one of these types,then the cast will succeed. Otherwise,the cast fails.

If a dynamic_cast to a pointer type fails,the result is 0. If a dynamic_cast to a
reference type fails,the operator throws an exception of type bad_cast

但是,我在这里写了一段代码片段:

struct A {};
struct B : private A // note: *private* inheritance
{
  A* test() {
    return dynamic_cast<A*>(this);
  }
};

int main()
{
  B b;
  if(b.test()==nullptr)
      throw 1;
}

在上面的代码片段中,A只是B的私有基础,c引物不考虑它.但是,此代码段可以编译并运行而不会出错.底漆有错吗?

解决方法

这一切都是引物部分的一个不幸的措辞.它将两种类型的演员阵容组合成一个句子,然后错过了结果.

转换为基类,不需要运行时强制转换操作.它是,as T.C. says,纯粹是一个静态结构.和T.C.一样.引用它,它需要一个accessbile基础,而不是公共基础.所以你的代码一切都很好.

对于运行时强制转换(向下转换),C标准对操作数和动态强制转换中涉及的类型提出了要求,以使其成功.该类必须是公开派生的,否则实现没有义务成功转换继承链.我的意思是,它理论上可以使演员成功,但根据规范“the runtime check fails”,这并没有留下太多的余地.

但无论哪种方式,你的程序都没有任何错误会使它无法编译,也没有任何东西会导致任何类型的运行时错误.

如果我们将您的代码更改为强制转换而不是强制转换,则此处为example that doesn’t even build:

struct A {};
struct B : private A // note: *private* inheritance
{
  A* test(B* p) {
    return dynamic_cast<A*>(p);
  }

  friend B* foo(A*);
};

B* foo(A* a) {
    return dynamic_cast<B*>(a);
}

int main()
{
  B b;
  *foo(&b);
}

A是foo中B的可访问基础,然而,演员阵容是不正确的.

将引物重新引入过程的最小变化是将“从目标类型公开派生的类类型”变为“从目标类型可访问地派生的类类型”.由于publicly available errata中没有任何类型,我们可以猜测这是一个尚未被指出的编辑错误.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读