potisanのプログラミングメモ

趣味のプログラマーがプログラミング関係で気になったことや調べたことをいつでも忘れられるようにメモするブログです。はてなブログ無料版なので記事の上の方はたぶん広告です。記事中にも広告挿入されるみたいです。

C++ STLのスマートポインタが&演算子をオーバーロードしないのはshared_ptrのため?

C++によるWindows開発ではATLとSTLが使えます。ATLがメモリ管理クラス(CComPtrCComHeapPtr)に&演算子を実装して内部ポインタのポインタ取得を可能にしている一方、STLはスマートポインタ(unique_ptrshared_ptr)に&演算子を実装していません。STLの方が広く使われているのにどうしてだろうと不思議に思っていたのですが、shared_ptrもスマートポインタであることを思い出して納得しました。

STLshared_ptrは複数のインスタンスが参照カウントを使ってメモリを共有します。これが&演算子で内部ポインタのポインタを返す場合、あるインスタンスのデータを変更したつもりがメモリを共有する全インスタンスのデータを変更してしまいます。

最初から上記の仕様であれば不都合は生じないと思いますが、shared_ptrが生のポインタを機能拡張したスマートポインタであることを考えると余分な機能が付きすぎてしまう印象があります。想像ですが、以上のような理由からSTLのスマートポインタは&演算子による内部ポインタのポインタ取得をサポートしていないと考えられます。

実はATLもCStringT&演算子オーバーロードしていません。おそらくですが、参照カウントを使用しないCComPtrCComHeapPtrと違って内部のCStringDataが参照カウンタを使っていること、つまりshared_ptrと似たような実装であることに起因すると考えられます。

なお、他のC++用ライブラリであるWILではuwil::nique_ptr&演算子を定義すると同時にwil::unique_anyにはwil::out_paramというアダプタクラスを用意することで上記の共有問題を解決しています。あまり有名ではないですがWindows環境の趣味開発では便利なので、ぜひ一度。