C 共有体

提供:yonewiki

C++へ戻る


※このページではC言語にも存在していたという意味で記事タイトルがC 共有体になっていますが、
C++でも同様です。C++だけの機能がある場合は明記します。

共有体

構造体と同じくクラスとしての機能を持っていますが、共有体で宣言された変数群の場合、共有体変数として宣言されたもののうちどれか一つを使い、変数のサイズは共有体の中で宣言された変数のうちで最も大きいサイズのものになるという独特の機能であるということです。通常は共有体で宣言した変数の内のどの型の変数を使ったかを記憶する変数も一緒に管理しておくので、構造体やクラスの中に共有体が定義されて利用されます。


共有体の基本的な使い方と、実際の利用方法をサンプルにて示したいと思います。


基本的には以下のようなサンプルのように宣言して、共有体内で宣言した変数のどれかを利用するような使い方になります。

#pragma once
#include <iostream>

using namespace std;

union uniNumber{
  char  chNum;
  int   nNum;
  float fNum;
  long  lNum;
  double dNum;
};
int _tmain(int argc, _TCHAR* argv[]){
  uniNumber uniNumberTest;
  uniNumberTest.nNum = 256;
  uniNumberTest.dNum = 5.56789;

  printf("%d\n",uniNumberTest.nNum);
  printf("\n");
  printf("%f\n",uniNumberTest.dNum);
  printf("\n");
}

という具合に共有体を使いますが、共有体は構造体と違って、定義された変数の中のどれか一つの型で使うというものですので、複数ある中の一番大きな型のメモリサイズを確保した実体が作られ、使い方によっては、それより小さなメモリサイズしか使わない変数としても使うことができるというものです。したがって上記のようなプログラムのようにdNumという変数を利用すると、nNumの内容はdNumで書き換えられることになります。結果としては以下のような出力になります。

-188291366

5.567890

nNumを出力しようとしても、すでに訳のわからない値になってしまっていることがわかると思います。先に述べたように共有体はこれ単独では、どんな型として共有体を利用しているかわからないので、共有体をどんな型で利用したかを記憶しておく変数を準備する必要になります。dNumなら何番とかというフラグで管理して出力処理や抽出処理を切り替えます。文字なのか数値(整数、小数)なのかわからないけどどれかひとつをデータとして扱うような記憶領域が必要なセットなら、共有体を使って定義することで重複してメモリを確保せず、ひとつにまとめてメモリサイズを節約しようとするのが共有体です。大きなデータセットになれば、自然と利用したくなるようなものが共有体になります。もちろんメモリサイズを考慮しなければ、こんな特殊な変数を利用する必要もないので、使わないでメモリを浪費する適当なプログラムがあっても不思議ではありません。


うまく利用できる人ならば、きっと共有体の実体に名前をつけなくても良いことがわかると思います。クラスの中で定義した共有体であれば、共有体メンバ変数へ直接アクセスができるため、uniNumberTestのような実体の名前はいらないことになります。したがって実体の名前を定義しなくてもよいのです。これは構造体でも同じことで、クラスの中で使うことを前提としていれば、実体の名前は必要としない場合があります。C++/CLIでは認められていないみたいなので、このあたりの問題によって、C++/CLIに簡単に移行できないプログラムもあるのだと思います。例えばICUが提供しているUnicodeプロジェクトがその一例になると思います。このwikiの解説の文字列操作の項目で利用することになるものです。


C++へ戻る