potisanのプログラミングメモ

プログラミング素人です。昔の自分を育ててくれたネット情報に少しでも貢献できるよう、情報を貯めていこうと思っています。Windows環境のC++やC#がメインです。

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環境の趣味開発では便利なので、ぜひ一度。