c++转换指针到派生指针到基指针的例子

C++ cast pointer to pointer to derived to pointer to pointer to base example

本文关键字:指针 派生 转换 c++      更新时间:2023-10-16

我有一个指向派生类的指针表。该程序使用许多使用这些表中的条目的小类。必须定期交换所有这些小类,目的是让它们使用表中不同类中的数据,但它们只使用基类数据。这些小类使用指针指向表的表项,但这些指针实际上是指向基类的指针。单独来说,它是这样的,下面的代码在gcc 4.8.2中可以工作(真正的东西有复杂的类;这只是一个例子)

#include <iostream>
class Base {public: int i;};
class Derived : public Base {public: int j;};
int main() {
  Base **b;
  Derived *table[2];
  table[0] = new Derived; table[0]->i = 1; table[0]->j = -2;
  table[1] = new Derived; table[1]->i = 4; table[1]->j = -5;
  b = reinterpret_cast<Base**>(&(table[0]));
  std::cout << "first: " << (**b).i << " " << "n";
  b = reinterpret_cast<Base**>(&(table[1]));
  std::cout << "second: " << (**b).i << " " << "n";
  {Derived *temp; temp = table[0]; table[0] = table[1]; table[1] = temp;}
  b = reinterpret_cast<Base**>(&(table[0]));
  std::cout << "first switched: " << (**b).i << " " << "n";
  b = reinterpret_cast<Base**>(&(table[1]));
  std::cout << "second switched: " << (**b).i << " " << "n";
}

表不可能被破坏:它总是包含指向完全相同派生类类型的指针,所以理论上它们都可以交换。使用该表的类将永远只使用基类数据。如果reinterpret_castdynamic_caststatic_cast取代,则编译器会报错。现在,这一切都很好,除了这样的警告:"……这在大多数情况下会导致代码是特定于系统的,因此不可移植",以及其他非常可怕和严重的声明,这些声明来自那些显然知道很多的固执己见的专家。

上述是reinterpret_cast的合理和安全的使用吗?

既不安全也不合理。

首先有点咆哮。reinterpret_cast是一个大刀阔斧的人。最后的武器。它不安全。这是不友好的。它不会保护你免受你自己的伤害。它不应该成为你的首选工具。如果static_cast不"工作",并且你不理解编译器告诉你什么,你不应该只是在那里敲reinterpret_cast。相反,您应该首先尝试理解编译器的错误消息,然后修复实际的问题。

结束咆哮。现在在你的例子中:

b = reinterpret_cast<Base**>(&(table[0]));

table是指向Derived的指针数组。因此,您正在尝试从指向Derived的指针转换为指向Base的指针。您应该做的是将指向Derived的指针转换为指向Base的指针,如下所示:

Base* b = static_cast<Base*>(table[0]);

然后使用它:

std::cout << "first: " << (*b).i << " " << "n";

但是因为DerivedBase的直系后代,你甚至不需要显式强制转换。这样就可以了:

Base* b = table [0];

更好的是,既然你真的不需要一个指针,为什么不直接获取一个引用呢?

  Base& b = *table[0];
  std::cout << "first: " << b.i << " " << "n";