「More C++ Idioms/具象データ型(Concrete Data Type)」の版間の差分

削除された内容 追加された内容
Yak! (トーク | 投稿記録)
現内容を日本語に翻訳
1 行
=<center>具象データ型(Concrete Data Type)</center>=
=== Intent意図 ===
フリーストア(ヒープ)を用いた動的な割り当てを許可あるいは禁止する事でオブジェクトのスコープと生存期間を制御する。
To control object's scope and lifetime by allowing or disallowing dynamic allocation using the free store (heap)
=== Also Known As別名 ===
 
=== Motivation動機 ===
C++ にはオブジェクトの生存期間の制御とプログラムレベルでの識別子(変数)への束縛に対して 2 つの方法がある。1 つ目は、スコープ変数とオブジェクトであり、スコープが終了した後速やかに破棄される(''例えば'' 関数スコープの整数変数等)。2 つ目は、スコープ変数(しばしばポインタ)とフリーストアに動的に割り当てられたオブジェクトである。この場合、変数のスコープが終了した際に変数自体は存在しなくなるがオブジェクトの生存期間は継続する(''例えば'' シングルトンやウィンドウオブジェクト等)。 具象データ型(Concrete Data Type)イディオムを用いる事で、生存期間に対する上記 2 つの選択のいずれかを強制する事が出来る。
C++ provides two ways of controlling lifetime of an object and binding it with a program level identifier (variable). First is a scoped variable and an object, which are destroyed immediately after the scope ends (''e.g.,'' function scope integers). Second is a scoped variable (often a pointer) and a dynamically allocated object in the free store. In this case, at the end of the scope of the variable, the variable ceases to exist but the object's lifetime continues (''e.g.,'' singletons, a window object). It is possible to force the choice of the lifetime of an object either first way or the second using the Concrete Data Type idiom.
=== Solution and Sample Code解法とサンプルコード ===
このイディオムは、目的を達成する為に単純にクラスレベルのアクセス指定子(private, protected)を使う。以下のコードは MouseEventHandler クラスに動的な割り当てを強制する方法を示す。
This idiom simply uses class level access modifiers (private, protected) to achieve the goal.
The following code shows how a MouseEventHandler class forces dynamic allocation.
 
<source lang="cpp">
16 ⟶ 15行目:
virtual ~EventHandler () {}
};
class MouseEventHandler : public EventHandler // Note inheritance継承に注目。
{
protected:
~MouseEventHandler () {} // A protected virtual destructor.な仮想デストラクタ。
public:
MouseEventHandler () {} // Publicpublic Constructor.なコンストラクタ。
};
int main (void)
{
MouseEventHandler m; // Aデストラクタが scopedprotected variable is not allowed as destructor is protected.なのでスコープ変数は許可されない。
EventHandler *e = new MouseEventHandler (); // Dynamic allocation is allowed動的な割り当ては許可される。
delete e; // Polymorphic多態的な delete. Does not leak memory.はメモリリークを起こさない。
}
</source>
動的な割り当てを強制する別の方法として、コンストラクタへの直接のアクセスをさせず代わりに動的に割り当てられたオブジェクトを返す静的関数 instance() を提供する方法がある。これはシングルトンデザインパターンとよく似ている。さらに言えば、メモリを解放するのに多態的な delete は必ずしも必要ではない。メンバ関数 destroy() によって仮想関数テーブルポインタに必要な領域を節約した上で目的を達成する事が出来る。
Another way to force dynamic allocation is to prevent direct access to the constructor and instead provide a static function instance() to return a dynamically allocated object. It is in many ways similar to the Singleton design pattern. Moreover, it is not strictly necessary to use polymorphic delete to reclaim memory. A member function destroy() can serve the purpose saving the space required for a v-table pointer.
 
<source lang="cpp">
class MouseEventHandler // Note no inheritance継承がない点に注目。
{
protected:
MouseEventHandler () {} // Protectedprotected Constructor.なコンストラクタ。
~MouseEventHandler () {} // A protected, non-virtual destructor.で非仮想なデストラクタ。
public:
static MouseEventHandler * instance () { return new MouseEventHandler(); }
void destroy () { delete this; } // Reclaim memory.メモリを解放する。
};
</source>
 
このイディオムの対極に当たるのがスコープ変数(自動変数)の強制である。これは private な new 演算子を用いる事で実現できる。
An opposite extreme of this idiom is to force scoped variable (a.k.a. automatic variable) only. It can be achieved using a private new operator.
 
<source lang="cpp">
50 ⟶ 49行目:
{
private:
static void * operator new (unsigned int size); // Disallow dynamic allocation動的な割り当てを許可しない。
static void * operator new (unsigned int size, void * mem); // Disallow 配置形式(placement) new as well.も同様に許可しない。
};
int main (void)
{
ScopedLock s; // Allowed可能。
ScopedLock * sl = new ScopedLock (); // Standard標準の new and及び nothrow new are not allowed.は許可されない。
void * buf = ::operator new (sizeof (ScopedLock));
ScopedLock * s2 = new(buf) ScopedLock; // Placement配置形式(placement) new is also not allowedも許可されない。
}
</source>
 
ScopedLock オブジェクトは標準的な new 演算子、nothrow な new、配置形式(placement) new のいずれによっても動的に割り当てる事が出来ない。
ScopedLock object can't be allocated dynamically with standard uses of new operator, nothrow new, and the placement new.
 
=== Known Uses既知の利用 ===
 
=== Related Idioms関連するイディオム ===
 
=== References ===
* [http://users.rcn.com/jcoplien/Patterns/C++Idioms/EuroPLoP98.html#ConcreteDataType Concrete Data Type] - J. Coplien.
<noinclude>
[[Category:{{BASEPAGENAME}}|{{SUBPAGENAME}}]]
[[en:More C++ Idioms/Concrete Data Type]]
</noinclude>
[[Category:{{BASEPAGENAME}}|{{SUBPAGENAME}}くしようてーたかた]]