「pimpl」のすゝめ

@Rayerd shared_ptr 相当のものを pimpl で包んで実現すれば、クライアントコード側では中で多態が行われてることを意識しないで書けますよね。
2010-08-18 20:16:48
public 継承を使った多態というのは、基本的に「内部の実装の詳細は違うけど、外から見たら全部同じ」場合に使うもんだと解釈していて
2010-08-18 20:25:17
要するに、構築だけ違って、操作は全く一緒。それだったら一つのクラスにまとめてしまったほうが分かりやすいんでないの? っていうのが僕の考えだったりするのです。
2010-08-18 20:26:14
そうした場合、「設計当初は内部実装が場合によって全然違うように思えたけど、実は一つの実装でなんとかなるよ!」とかなった場合に
2010-08-18 20:27:22
まぁ、そういうことです。 クラスを使う側はその実装なんて気を配らないから、 pimpl を使ってもよし、直接 shared_ptr なり実装の詳細を持たせてもよし。
2010-08-18 20:29:56
shared_ptr<Image> img = createImage( filename ); int const width = img->width(); より、Image img( filename ); int const width = img.width(); だろ
2010-08-18 20:33:03
しつこくなるけど、もう一回まとめ。具体例で。ファイルの拡張子からファイルフォーマットを識別して、それにあった内部実装を選択する。しかし内部実装が違っても、外部から見たら全く同じ、という場合を考えると
2010-08-18 20:47:04
抽象基底クラス ImageFile と、 ImageFile* なり shared_ptr<ImageFIle> を返すファクトリを用意して、多態を使って何かする、というデザインパターンは、僕はあんまり好きじゃない。
2010-08-18 20:48:59
使う側の都合としては、ファイルフォーマットによって内部表現が変わる、なんてのは全く関係ないことで、とにかく使えればいいのです。
2010-08-18 20:50:54
だったらスマポとか返すファクトリを用意するんじゃなくて、普通に一つのクラスとして作ったほうがいいだろ? というのが僕の主張。
2010-08-18 20:52:45
@SubaruG 自分の場合、「どうせコピー重いしむしろ共有のセマンティクスが欲しい→shared_ptr→このアプリ内どうせコピーが1ヶ所も現れないならImageは抽象クラスでファクトリ関数createImage提供でもいいや」という考えに行ってしまう。
2010-08-18 20:55:12
@egtra Image は immutable クラスとして用意するのが自然なので、普通に内部では共有させますね。僕の場合は。
2010-08-18 20:56:51
仮に生成部分が動的に切り替わらない場合には、普通に別クラスに分けて、で必要に応じて type erasure を使う。
2010-08-18 20:58:07
@SubaruG ああ、Image a; Image b = a;としたら、aとbは同一の実体を保持するということですか?ならありですね。
2010-08-18 21:01:22
@egtra immutable じゃない場合にどうするかは難しいのですが。むしろ、その場合には const を指定できる shared_ptr の方が優れてるかもしれません。
2010-08-18 21:05:36