簡體   English   中英

在C ++中將結構指針轉換為聯合指針

[英]casting structure pointer to union pointer in C++

我有一個包含各種struct成員的Union。

union U {
    struct S1 as_s1;
    struct S2 as_s2;
    …
};

如何在C ++中將struct as_s1的指針轉換為Union U的指針?

我知道是不是因為這個 ,它可以用C鑄造輕松完成。 但是我想使用C ++的Advance類類型轉換的功能而不會引起任何錯誤。

來自標准6.9.2.4。

如果滿足以下條件,則兩個對象a和b是指針可互換的

  1. 它們是同一對象,或者
  2. 一個是標准布局聯合對象,另一個是該對象的非靜態數據成員(12.3),
  3. 一個是標准布局類對象,另一個是該對象的第一個非靜態數據成員,或者,如果該對象沒有非靜態數據成員,則是該對象的第一個基類子對象(12.2),或者
  4. 存在一個對象c,使得a和c是指針可互換的,而c和b是指針可互換的。

如果兩個對象是指針可互換的,則它們具有相同的地址,並且可以通過reinterpret_cast(8.2.10)從指向另一個的指針獲得指向一個的指針。

這意味着您可以使用reinterpret_cast將它們彼此轉換。 但是,您不能訪問錯誤類型的內存。 例如,以下是定義良好的代碼:

#include <iostream>

struct S1 {
  int i;
};

struct S2 {
  short int i;
};

union U {
  struct S1 as_s1;
  struct S2 as_s2;
};

void printUnion(U* u, int type) {
  if (type == 0){
    S1 *s1 = reinterpret_cast<S1*>(u);
    std::cout << s1->i << std::endl;
  } else {
    S2 *s2 = reinterpret_cast<S2*>(u);
    std::cout << s2->i << std::endl;
  }
}

int main() {
  S1 s1{1};
  printData(reinterpret_cast<U*>(&s1), 0);
  S2 s2{2};
  printData(reinterpret_cast<U*>(&s2), 1);
}

但是,如果您給printData一個錯誤的類型參數,則該行為是不確定的。

在c ++中,很難想象一個需要良好設計的程序將需要強制轉換。 在c中,如果您已經需要並集對象,則可能會用它來實現多態(當然那里沒有reinterpret_cast)。 雖然通常是用void*完成的。

此類指針轉換的正確轉換為reinterpret_cast:

#include <stdio.h>

struct S1 {
  int x,y;
};

struct S2 {
  double a,b;
};

union U {
  struct S1 as_s1;
  struct S2 as_s2;
};

int main() {

  struct S1 mys1;

  union U *uptr  = reinterpret_cast<union U*>(&mys1);
  uptr->as_s1.x = 42;
  printf("%d\n",mys1.x);

  return 0;
}

請注意,在本示例中,由於sizeof(struct S1) < sizeof(struct S2) ,並且您僅分配了S1大小的足夠內存,因此,如果嘗試在uptr->as_s1.b上執行任何操作,則會破壞堆棧。

暫無
暫無

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

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