13,009
回編集
(→実体化の禁止) |
|||
204行目: | 204行目: | ||
<br><br> | <br><br> | ||
== | == staticクラス == | ||
C++11以降では、デフォルトコンストラクタとデストラクタに<code>delete</code>キーワードを指定することにより、実体化を禁止することができる。<br> | ==== C++ 03以前 ==== | ||
全てのメンバが<code>static</code>メンバであるクラスを、staticクラス(静的クラス)と呼ぶ。<br> | |||
<br> | |||
staticメンバはオブジェクトを生成せずに使用できるため、staticクラスはインスタンス化の必要性がないことが特徴である。<br> | |||
そのため、staticクラスを記述する場合、インスタンス化を禁止するように設計する。<br> | |||
<br> | |||
C++でインスタンス化を禁止するには、コンストラクタを<code>private</code>にする。<br> | |||
<u>なお、コンストラクタが呼び出される可能性は無いため、実装を記述するべきではない。</u><br> | |||
<syntaxhighlight lang="c++"> | |||
class CSampleClass | |||
{ | |||
private: | |||
CSampleClass(); // 唯一のコンストラクタがprivateの場合は、インスタンス化できない | |||
}; | |||
</syntaxhighlight> | |||
<br> | |||
<u>問題点として、staticクラスのメンバ関数内において、コンストラクタを使用することである。</u><br> | |||
これは、クラス内のメンバへのアクセスとなるため、<code>private</code>であってもアクセス可能となり、コンパイルエラーにならない。<br> | |||
<br> | |||
これを、コンパイルエラーとする場合、コンストラクタの実装を記述しないことにより、リンクエラーを起こす方法を採ればよい。<br> | |||
(コンパイルは通るが、関数の実装が無いというリンクエラーが起きる)<br> | |||
<syntaxhighlight lang="c++"> | |||
void CSampleClass::func() | |||
{ | |||
CSampleClass *c = new CSampleClass(); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
staticクラスの価値は、任意の機能群を1つのスコープにまとめて記述できることである。<br> | |||
1つのヘッダファイルにstaticクラスの機能群をまとめて、<code><クラス名>::<メンバ></code>のようにスコープを使用してアクセスすることができる。<br> | |||
<br> | |||
例えば、ファイルをコピーまたは削除する機能は、それぞれ1つの関数で完結できるため、非staticクラスではメンバ変数を持つ必要はない。<br> | |||
以下の例では、staticクラスを定義して、ファイルをコピーまたは削除する機能を記述している。<br> | |||
<syntaxhighlight lang="c++"> | |||
class FileSystem | |||
{ | |||
public: | |||
static void Copy(const char* src, const char* dest); | |||
static void Delete(const char* path); | |||
private: | |||
FileSystem(); | |||
}; | |||
</syntaxhighlight> | |||
<br> | |||
ただし、スコープを限定するという目的の場合、名前空間を使用する方がよい。<br> | |||
この場合、コンストラクタを<code>private</code>にする処理も不要である。<br> | |||
<syntaxhighlight lang="c++"> | |||
namespace FileSystem | |||
{ | |||
void Copy(const char* src, const char* dest); | |||
void Delete(const char* path); | |||
} | |||
FileSystem::Copy("sample.txt", "sample_cp.txt"); | |||
FileSystem::Delete("sample.txt"); | |||
</syntaxhighlight> | |||
<br> | |||
==== C++ 11以降 ==== | |||
C++ 11以降では、デフォルトコンストラクタとデストラクタに<code>delete</code>キーワードを指定することにより、実体化を禁止することができる。<br> | |||
メンバに<code>delete</code>キーワードを指定する場合は、<code>public</code>に記述することがセオリーである。<br> | メンバに<code>delete</code>キーワードを指定する場合は、<code>public</code>に記述することがセオリーである。<br> | ||
<br> | |||
<code>final</code>は、継承をさせないことを明示的に宣言、または、派生クラスでの仮想関数のオーバーライドをさせないことを明示的に宣言するキーワードである。<br> | |||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
// C++11以降 | // C++ 11以降 | ||
class CSampleClass final | class CSampleClass final |