最近のコメント

最近のトラックバック

ウェブページ

2017年9月
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

他のアカウント

無料ブログはココログ

« 法学ド素人が自民党憲法改正草案に駄目出しする-その前に | トップページ | ジーン・シャープ「独裁体制から民主主義へ」を読んでみた−番外−非暴力行動198の方法 »

2017年3月27日 (月)

c++ でconst修飾をしても非constメンバ関数を呼べるトリッククラス。思いつき

c++ のstd::string は、constメンバ関数では本体の文字列が変更されることはない、という仕様がある。
このために、 const std::string では文字列の中身が変更されることはない。
まあ、c++にはmutable とか const_cast とかあるけれども。

そこで、ちょっと思いつきがあって、std::stringにちょっとだけ仕掛けをした拡張クラスを作ってみたら、const修飾してもstd::stringの非constメンバ関数を呼び出せてしまった。(もちろん、std::stringの拡張クラスでできた、というだけで const std::string が文字列を変えないことには違いない)。

追記: STLコンテナのデストラクタはvirtualではないと後で知りました。すると、std::string などの public な継承クラスを作るのは間違いですね。

ソース:
----

#include <iostream>
#include <string>

class mystring : public std::string{
private:
mystring* const pseudothis_ = this;
public:
mystring* pseudothis() const {return pseudothis_;}
};

int main(){
const mystring str;
std::cout << "str=" << str << std::endl;
str.pseudothis()->append("abc");
std::cout << "str=" << str << std::endl;
*(str.pseudothis()) += "def";
std::cout << "str=" << str << std::endl;
return 0;
}

----

実行結果
----

str=
str=abc
str=abcdef

----

手抜きクラスなので、自動生成された(空文字列で初期化の)デフォルトコンストラクタしかないが、const 修飾されてもstd::stringの非メンバ関数を呼び出せるため文字列の変更ができる。

しかし、ちょっと待て。これはstd::string の拡張クラスでなくても pseudo_ メンバ(とそのゲッター)のあるクラスを作れば、const修飾しても非constメンバ関数を呼び出せるクラスになるのではないか? c++の言語仕様でこのことが「保障」されるかどうかは断言できないが、かなり普遍性のあるトリックになりそうだ。
(もちろん、 class T {....} の中で T* const pseudothis _= this; というメンバを作るわけだ。)

« 法学ド素人が自民党憲法改正草案に駄目出しする-その前に | トップページ | ジーン・シャープ「独裁体制から民主主義へ」を読んでみた−番外−非暴力行動198の方法 »

C/C++言語」カテゴリの記事

パソコン・インターネット」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/525300/65070843

この記事へのトラックバック一覧です: c++ でconst修飾をしても非constメンバ関数を呼べるトリッククラス。思いつき:

« 法学ド素人が自民党憲法改正草案に駄目出しする-その前に | トップページ | ジーン・シャープ「独裁体制から民主主義へ」を読んでみた−番外−非暴力行動198の方法 »