【问题标题】:Dynamic_Cast vector elementsDynamic_Cast 向量元素
【发布时间】:2015-08-20 09:02:50
【问题描述】:

我正在尝试创建一个包含基类元素的新类型向量。我所做的是将基类向量元素动态转换为派生类型,以便应用我在派生类中添加的一些方法。

这就是我大致所做的:

std::vector<BaseClass *> A;
std::vector<DerivedClass *> B;
DerivedClass *m = new DerivedClass;
std::vector<BaseClass *>::const_iterator iterator = A.begin();
AMD_STD::vector<BaseClass *>::const_iterator iteratorEnd = A.end()

for(; iterator!= iteratorEnd; ++iterator)
{
 m = dynamic_cast<DerivedClass *>(*iterator); 
 B.push_back(m);
}
 B->MyMethod();

问题是当我尝试应用该方法时,我有一个 NULL 指针,它会产生执行错误。 我认为问题是由于 dynamic_cast 失败。谁能帮我解决这个问题。 提前致谢。

【问题讨论】:

  • 请发布一个实际重现问题的最小代码,以便我们看到它。从您发布的 sn-p 很难看出 - 从概念上讲它没有任何问题(通常 - 它不会编译)。
  • 您可以发布一个mvce,我们可以运行它并显示您的问题吗? B-&gt;MyMethod() 不会编译,你永远不会填充 A。
  • 好吧,dynamic_cast 是代码异味。您可能应该重新考虑您的设计。
  • 这是整个代码吗?似乎不正确。 A 没有任何元素。同样为 m(DerivedClass *m = new DerivedClass;) 完成的内存分配似乎没用。

标签: c++ iterator dynamic-cast


【解决方案1】:

如果dynamic_cast&lt;DerivedClass*&gt;(*iterator) 失败并在*iterator 不是nullptr 时返回nullptr,那么您已经向是 类型BaseClass* 的向量添加了一个元素,但是不是类型DerivedClass*。就这么简单。

尽管您没有展示任何添加矢量元素的代码,但您明确表示“这就是我大致所做的”,这让竞技场为其他真相敞开了大门。

【讨论】:

    【解决方案2】:

    显然,当B 是vector 时,B-&gt;MyMethod(); 将无法编译,但假设您稍后尝试迭代B 并在其中的每个指针上调用MyMethod,您的问题将是nullptrs 您已推送到 vector B。为避免将它们放在那里,请仅在它们不为空时推送:

    for( ; iterator!= iteratorEnd; ++iterator)
         if (m = dynamic_cast<DerivedClass *>(*iterator))
             B.push_back(m);
    

    另外,我建议将变量生命周期本地化到尽可能小的使用范围并使用 C++11 表示法:

    for (auto& base_ptr : B)
         if (DerivedClass* p = dynamic_cast<DerivedClass *>(base_ptr))
             B.push_back(p);
    

    【讨论】:

    • “简洁就是智慧”不是一个普遍的常数。为了维护者的利益,越明确越好。 if((m = dynamic_cast&lt;DerivedClass *&gt;(*iterator)) != nullptr)。另外,我相信有些编译器会给你一个条件中括号赋值的警告。
    • 我认为 Tony 的代码是惯用的,几乎任何使用过 dynamic_cast 的人都会看到它在做什么。
    • @Medinoc:我不同意与nullptr 进行比较是有用的——将指针和整数隐式转换为true/false 值是直观的,值得作为C++ 程序员早期学习;确实有些编译器会发出警告...而且该死的痛苦,因为如果您添加额外的括号,C++ 不允许您创建 if-scoped 变量(就像我在第二个代码 sn-p 中所做的那样)。我建议禁用该特定警告(也许偶尔启用并找出没有问题的情况)。
    • 我不会争论无作业测试中隐含的真/假,但是当测试包含作业时,最好是明确而不是冒险。
    • @Medinoc:这对于本地化形式 if (DerivedClass* p = dynamic_cast&lt;DerivedClass *&gt;(base_ptr)) 来说甚至是不可能的 - 添加与 nullptr 的比较只能在分配之前产生 bool,这会阻止正确分配给指针。而且我不认为明确的风险较小 - (a = b) != nullptr 和 (a = b) == nullptr 之间的区别相对微妙;通过仅在产生影响时使用== nullptr(反转布尔意义),它可以更好地突出重要性。我们必须同意不同意...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    • 1970-01-01
    • 2012-08-04
    • 2017-11-22
    • 2020-04-01
    • 1970-01-01
    相关资源
    最近更新 更多