c++ - 将指向派生类的指针数组转换为指向基类的指针数组

标签 c++ arrays pointers

下面是一些说明问题的代码:

#include <iostream>

class Base {
};

class Derived : public Base {
};

void doThings(Base* bases[], int length)
{
    for (int i = 0; i < length; ++i)
        std::cout << "Do ALL the things\n";
}

int main(int argc, const char * argv[])
{
    Derived* arrayOfDerived[2] = { new Derived(), new Derived() };
    doThings(arrayOfDerived, 2); // Candidate function not viable: no known conversion from 'Derived *[2]' to 'Base **' for 1st argument

    // Attempts to work out the correct cast
    Derived** deriveds = &arrayOfDerived[0];
    Base** bases = dynamic_cast<Base**>(deriveds); // 'Base *' is not a class

    Base** bases = dynamic_cast<Base**>(arrayOfDerived); // 'Base *' is not a class

    // Just pretend that it should work
    doThings(reinterpret_cast<Base**>(arrayOfDerived), 2);

    return 0;
}

Clang 会产生注释中给出的错误。问题是:“是否有正确的方法将 arrayOfDerived 转换为 doThings 可以接受的东西?

加分:

  1. 为什么 clang 在给定行上产生错误“'Base *' is not a class”?我知道Base*不是一个类,它是一个指针。试图告诉我的错误是什么?为什么有 dynamic_cast被设计成在dynamic_cast<T*>东西T必须是一个类(class)吗?
  2. 使用 reinterpret_cast 有什么危险?强制一切正常工作?

一如既往的感谢:)

最佳答案

没有。您在这里要求的是协变数组类型,这不是 C++ 的特性。

reinterpret_cast 或 C 风格转换的风险在于,虽然这适用于简单类型,但如果您使用多重继承或虚拟继承,它会失败得很惨,并且还可能破坏虚函数的存在(取决于实现)。为什么?因为在那些情况下,static_castdynamic_cast 实际上可能会更改指针值。即给定

class A {
  int a;
};

class B {
  string s;
};

class C : public A, B {
  double f[4];
};

C *ptr = new C();

除非类为空,ptr == (A *)ptr 和/或 ptr == (B *)ptr 将为 false。只需要一点时间就可以弄清楚为什么一定是这样。如果你使用单继承并且没有虚表,那么可以保证子类的布局与父类(super class)的布局相同,后面是子类中定义的成员变量。但是,如果您有多重继承,则编译器必须选择以某种顺序或其他方式对类进行布局;我不确定 C++ 标准对此有何规定(您可以检查 - 它可能以某种方式定义或限制布局顺序),但无论它选择什么顺序,很明显其中之一强制转换必须导致指针值发生变化。

关于c++ - 将指向派生类的指针数组转换为指向基类的指针数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24785760/

相关文章:

C++ 变量作用域

c++ - 函数指针存储的地址在哪里

pointers - 在 Golang 中取消引用 map 索引

c++ - resize 是否保证 std::valarray 归零?

C++ Qt 查找/dev/中的每个磁盘

javascript - 将函数附加到数组

php - 使用 $_POST 从 HTML 中获取选择选项值

java - 如何在一个类中创建对象并将它们保存在另一个类的数组中?

c - C 代码中的结构体和指针

c++ - 获取鼠标在 x11 窗口中的相对位置