読取専用インスタンスで使えるメソッドを定義する - C++ プログラミング

PROGRAM


読取専用インスタンスで使えるメソッドを定義する

C++ のクラスインスタンスは、読み取り専用として扱うことができます。

const CMyClass* instance;

このように、変数 instance の型としてクラス型を指定するのと合わせて const を指定することで、そのインスタンスは読み取り専用として扱うことができます。

戻り値や引数についても指定できますし、クラス型の参照についても使えます。

const CMyClass* instanceAtIndex(size_t index);

void addInstance(const CMyClass& instance);

このようにして const が指定されたインスタンスは、属性の値は全て const 扱いとなり編集できなくなります。

 

そしてもうひとつ重要なのが、この const が付けられたインスタンスでは、普通に実装したメソッドの呼び出しができなくなるところです。

C++ では、普通に定義したメソッドは const が指定されたインスタンスでは使用できないようになっているので、逆に const を指定したインスタンスで使用したいメソッドは、プロトタイプ宣言時に明示する必要があります。

 

const 指定のメソッド定義

const が付けられたインスタンスで呼び出せるメソッドには、次のように、末尾に const を指定します。

char* toString(char* buffer, size_t bufferLength) const;

こうすることで、このメソッドは const が指定されたインスタンスからでも使用できるようになります。

このとき、この中でアクセスする属性の型には自動的に const が付いて書き込めないようになっているので、実装する際は、属性の値は読み込みだけでプログラムを書く必要があります。

 

なお、このように末尾に const を付けたメソッドと、付けていないメソッドは、同じ名前や引数であっても別のものとして扱われます。

そのため、次の 2 つはひとつのクラスに共存できます。

char* description();

const char* description() const;

戻り値の型も違うものを指定できます。

そのため、たとえば属性で保持しているクラスインスタンスを返す時、const の場合はそのインスタンスを const で返すことで書き換えられないようにし、非 const の場合は非 const で返すことで、受け取ったインスタンスを自由に編集できるようにすることも可能です。

 

const 指定のメソッド呼び出し

const 指定したメソッドの呼び出しは、普段通り const は付けずに呼び出します。

value = instance->description();

このとき、const が付いているメソッドを実行すべきか、付いていないメソッドを実行すべきかは、コンパイラが自動で判断します。

  1. インスタンスが const 指定されている場合は、const が指定されたメソッドを呼び出します。const が指定されたメソッドがない場合はコンパイルエラーになります。
  2. インスタンスが const 指定されていない場合は、const が指定されていないメソッドがあればそれを優先的に呼び出します。const 指定されているメソッドしかない場合は、そちらを呼び出します。

このように、const が指定されていないインスタンスでは const が指定されていないメソッド優先で、const が指定されているインスタンスでは const が指定されているメソッド限定で、メソッドが呼び出されることになります。

 

const メソッド内で属性の値を変更する

読み取り専用のメソッドとして const を付けて定義した場合でも、内部で結果をキャッシュしたい場合など、属性に書き込みたい場合があります。

そんなときには、属性をいったん const 無しの型に強制キャストすることで、値を編集することができるようになります。

 

たとえば、次の属性が定義されていたとします。

int m_cache;

これを const を指定したメソッドで使おうとすると "const int" 型として扱われるのですが、ここに書き込みたい場合は、メソッド内で次のように実装します。

int* cache = (int*)&m_cache;

 

*cache = 100;

たとえばこのように、いったん int* 型のポインターにしてあげることで、そのポインターが指すアドレスに値を書き込むことが可能です。


[ もどる ]