C++/CLI文法リファレンス - 値型の定義
スタック領域に確保される値型を定義します。
使用に適した状況
参照型のように、継承を伴う複雑なオブジェクトを定義したくない場合、値型の検討をしましょう。ただし、頻繁に使用するのは参照型であり、値型が適している状況の方が少ないです。
サンプル
/*----------------------------------------------------
*
* 値型
*
----------------------------------------------------*/
using namespace System;
value struct ValueTypeSample
{
//内部クラス
ref class InnerClass{ };
public:
//定数
static const int ConstValue = 1;
//リテラル値
literal int MIN = -1;
//読み取り専用フィールド
initonly int Value;
//静的フィールド
static int StaticValue = 100;
//スカラプロパティ
property int PropertyValue
{
int get(){ return this->m_value; }
void set( int newValue ) { this->m_value; }
}
//クラス レベルのインデックス付きプロパティ
property int Default [int]
{
int get( int index ) { return 0; }
void set ( int index, int newValue ) { }
}
//インデックス付きプロパティ
property int NamedIndexProperty [int]
{
int get( int value ){ return 0; }
}
//静的プロパティ
static property int StaticProperty
{
int get() { return ConstValue; }
}
//トリビアル・スカラ・プロパティ
property int TrivialProperty;
//デフォルトコンストラクタは定義でき機内
//ValueTypeSample( ) { }
//静的コンストラクタ
//動作が難しいのでお勧めできない
static ValueTypeSample() { }
//メソッド
void Method( ) { }
//イベント
event EventHandler< EventArgs^ >^ Event;
private:
//フィールド
int m_value;
};
//こっちでもOK
//アクセス修飾子が規定でprivateになる
value class Foo
{
};
//値型(構造体)は継承できない
//value struct Bar : Foo {};
int main()
{
//gcnewを使わない点に注意
ValueTypeSample obj = ValueTypeSample();
return 0;
}
文法
value structもしくはvalue classキーワードを指定します。どちらを使ってもよいのですが、参照型でclassを使用したら、値型ではstruct を使用するとよいでしょう。そうすると、値型と参照型が判別しやすくなります。
個人的には、値型をvalue structで定義でしています。理由は、データを強調したのが構造体だと考えているからです。オブジェクトというよりも、データと呼んだ方が良いような単純なオブジェクトは、命令型のイメージを持つ構造体を使用するとしっくりします。
解説
.NETでは型が、参照型と値型に大別されています。違いはメモリ管理の方法と、アクセス修飾子および定義できるメンバーです。また、値型は継承ができない点も忘れてはなりません。つまり値型は、参照型と比べると単純なオブジェクトを実装するのに使用するとよいでしょう。
注意しなくてはならいのは、スタック領域に確保されるからと言って、パフォーマンス上の早とちりだけで値型に決定してはならないという事です。スタック領域に確保され、ガベージコレクションの管理対象とならないと聞けば誰しも、パフォーマンスが向上すると考えるでしょう。しかしながら、コンパイラやJITなどの最適化の効果もありますし、あらゆる状況でスタックに積むのが最善とは言えません。スタックに積むことにより、逆にパフォーマンスが低下する可能性があります。そうしたことから、基本的にパフォーマンスで考えるのではなく、オブジェクト指向設計に基づき、継承の有無などの特徴から値型にするのか、参照型にするのかを決定するべきだと思います。