簡體   English   中英

C ++將指針轉換為指向派生的指針,指向指向基本示例的指針

[英]C++ cast pointer to pointer to derived to pointer to pointer to base example

我有一個指向派生類的指針表。 該程序使用許多小類,這些小類使用這些表中的條目。 必須定期交換所有這些小類,目的是它們使用表中其他類中的數據,但它們僅使用基類數據。 因此,那些小類使用指向表條目的指針,但是這些指針實際上是指向基類指針的指針。 孤立地是這樣,下面的內容在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_cast替換為dynamic_caststatic_cast則編譯器會抱怨。 現在,一切都很好,除了這樣的警告:“ ...在大多數情況下,其結果導致代碼是系統特定的,因此是不可移植的”,以及由有見識的專家做出的其他真正令人恐懼和嚴厲的聲明,這些專家顯然都知道很多。

以上內容是對reinterpret_cast的合理安全使用嗎?

既不安全也不合理。

首先有點。 reinterpret_cast是廣博的消息。 不得已的武器。 這不安全。 這不友好。 它不會保護您免受自己的傷害。 它不應該成為您的首選工具。 如果static_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";

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM