「C++の基礎 - クラス」の版間の差分

ナビゲーションに移動 検索に移動
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

案内メニュー