【问题标题】:Typesafe casting of structs in c++c++中结构的类型安全转换
【发布时间】:2021-01-27 07:45:21
【问题描述】:

我有一个两级结构的层次结构。我想将顶级父引用作为参数发送到函数中。 param 的实际值将是 bottomMost 子级。该函数应将子对象强制转换为 oneBelow the topParent 类型的结构。如果 child 属于强制转换的 parent,则函数应该成功,否则失败。

以下是设计:

struct Parent {
  ~Parent() = default;
}

struct Child1 : public Parent {
  ~Child1() = default;
}

struct Child2 : public Parent {
  ~Child2() = default;
}

struct Child11 : public Child1 {
  ~Child11() = default;
}

struct Child21 : public Child2 {
  ~Child21() = default;
}

someFunction (Parent* parent) {
  Child1 * child1 = dynamic_cast<Child1 *>(parent);
}

main() {
  Child11 child11;
  someFunction(child11);  // this should succeeed
  
  Child21 child21;
  someFunction(child21);  // this should throw

}

someFunction() 的工作是验证bottomMost 子节点是否属于特定父节点。但是 someFunction() 不会为 child21 抛出。有人可以了解如何实现吗?

这是一个适用于两级强制转换的示例。不知道怎么扩展为三层:How do I cast a parent class as the child class

感谢任何帮助。

【问题讨论】:

  • 只是使用多态不上桌吗?
  • dynamic_cast 不抛出。尝试动态转换后,您的函数将简单地获得nullptr。如果你想扔,那么if (parent != nullptr &amp;&amp; child1 == nullptr) throw ...
  • 您的代码现在甚至无法编译。您正在传递对象,而函数需要指针。请更正错别字。

标签: c++ pointers inheritance struct


【解决方案1】:

来自cppreference

如果转换失败并且 new-type 是指针类型,则返回该类型的空指针。如果转换失败并且 new-type 是一个引用类型,它会抛出一个与 std::bad_cast 类型的处理程序匹配的异常。

你的 new_type 是一个指针,因此它不会抛出。您提供的代码也无法编译(缺少函数的返回类型、传递错误的参数)。

这是您的代码,使用引用而不是指针来获取 dynamic_cast 以抛出。并且还提供了一个使用指针的版本,它也可以抛出。

#include <exception>
#include <iostream>

struct Parent {
  virtual ~Parent() = default;
};

struct Child1 : public Parent {
  virtual ~Child1() = default;
};

struct Child2 : public Parent {
  virtual ~Child2() = default;
};

struct Child11 : public Child1 {
  ~Child11() = default;
};

struct Child21 : public Child2 {
  ~Child21() = default;
};

// void someFunction(Parent* parent) {
//   Child1* child1 = dynamic_cast<Child1*>(parent);
//   if (!child1) {
//     throw std::bad_cast();
//   }
// }

void someFunction(Parent& parent) {
  Child1& child1 = dynamic_cast<Child1&>(parent);
}

int main() {
  Child11 child11;
  someFunction(child11);  // this should succeeed

  Child21 child21;
  try {
    someFunction(child21);  // this should throw
  } catch (std::bad_cast) {
    std::cout << "Exception caught.\n";
  }
}

我认为这个练习纯粹是学术性的。

【讨论】:

    猜你喜欢
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多