C ++转换指针指向派生到指针的指针指向基本示例

时间:2014-05-06 17:13:05

标签: c++ pointers

我有一个指向派生类的指针表。该程序使用许多使用这些表中的条目的小类。定期地,必须交换所有这些小类,目的是它们使用表中不同类的数据,但它们仅使用基类数据。所以那些小类使用指向表条目的指针,但这些指针实际上是指向基类指针的指针。孤立地,就是这样,下面的工作在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?

1 个答案:

答案 0 :(得分:4)

既不安全也不合理。

首先有点咆哮。 reinterpret_cast是一个广泛的选择。最后的武器。这不安全。这不友好。它不会保护你自己。它不应该是你选择的首选工具。如果reinterpret_cast没有“工作”并且您不理解编译器告诉您的内容,那么您不应该只在那里发出static_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";
相关问题