「pimpl」のすゝめ

@SubaruG センセが pimpl についてわかりやすくつぶやいていたのでまとめました。C++ ならでは(?)の解説ですね。
9
前へ 1 ・・ 3 4
普通のC++使い、銀天すばる @SubaruG

結局、二兎を追って中途半端になるだけなのかもにゃー。

2010-08-18 20:15:40
はるえす@イカのフレンズ @Rayerd

@SubaruG クライアントコードには多態が現れないと言うのは?

2010-08-18 20:15:42
普通のC++使い、銀天すばる @SubaruG

@Rayerd shared_ptr 相当のものを pimpl で包んで実現すれば、クライアントコード側では中で多態が行われてることを意識しないで書けますよね。

2010-08-18 20:16:48
普通のC++使い、銀天すばる @SubaruG

public 継承を使った多態というのは、基本的に「内部の実装の詳細は違うけど、外から見たら全部同じ」場合に使うもんだと解釈していて

2010-08-18 20:25:17
普通のC++使い、銀天すばる @SubaruG

要するに、構築だけ違って、操作は全く一緒。それだったら一つのクラスにまとめてしまったほうが分かりやすいんでないの? っていうのが僕の考えだったりするのです。

2010-08-18 20:26:14
普通のC++使い、銀天すばる @SubaruG

そうした場合、「設計当初は内部実装が場合によって全然違うように思えたけど、実は一つの実装でなんとかなるよ!」とかなった場合に

2010-08-18 20:27:22
普通のC++使い、銀天すばる @SubaruG

外からの見た目は全く変えず、実装を効率化出来る。

2010-08-18 20:27:44
普通のC++使い、銀天すばる @SubaruG

あと、コンストラクタとデストラクタを自然に使えるので嬉しい。

2010-08-18 20:28:25
普通のC++使い、銀天すばる @SubaruG

まぁ、そういうことです。 クラスを使う側はその実装なんて気を配らないから、 pimpl を使ってもよし、直接 shared_ptr なり実装の詳細を持たせてもよし。

2010-08-18 20:29:56
普通のC++使い、銀天すばる @SubaruG

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
普通のC++使い、銀天すばる @SubaruG

スマートポインタの知識を要求するライブラリはダメライブラリです。生ポインタを返すライブラリは滅びるべき。

2010-08-18 20:36:51
普通のC++使い、銀天すばる @SubaruG

@Rayerd stateパターンって知らなかったので検索してみました。たしかに、そのようにも使えますね。

2010-08-18 20:41:44
普通のC++使い、銀天すばる @SubaruG

しつこくなるけど、もう一回まとめ。具体例で。ファイルの拡張子からファイルフォーマットを識別して、それにあった内部実装を選択する。しかし内部実装が違っても、外部から見たら全く同じ、という場合を考えると

2010-08-18 20:47:04
普通のC++使い、銀天すばる @SubaruG

例えば画像ファイルにしますかにゃ。

2010-08-18 20:47:24
普通のC++使い、銀天すばる @SubaruG

抽象基底クラス ImageFile と、 ImageFile* なり shared_ptr<ImageFIle> を返すファクトリを用意して、多態を使って何かする、というデザインパターンは、僕はあんまり好きじゃない。

2010-08-18 20:48:59
普通のC++使い、銀天すばる @SubaruG

使う側の都合としては、ファイルフォーマットによって内部表現が変わる、なんてのは全く関係ないことで、とにかく使えればいいのです。

2010-08-18 20:50:54
普通のC++使い、銀天すばる @SubaruG

だったらスマポとか返すファクトリを用意するんじゃなくて、普通に一つのクラスとして作ったほうがいいだろ? というのが僕の主張。

2010-08-18 20:52:45
Egtra (ysk-noh) @egtra

@SubaruG 自分の場合、「どうせコピー重いしむしろ共有のセマンティクスが欲しい→shared_ptr→このアプリ内どうせコピーが1ヶ所も現れないならImageは抽象クラスでファクトリ関数createImage提供でもいいや」という考えに行ってしまう。

2010-08-18 20:55:12
普通のC++使い、銀天すばる @SubaruG

@egtra Image は immutable クラスとして用意するのが自然なので、普通に内部では共有させますね。僕の場合は。

2010-08-18 20:56:51
普通のC++使い、銀天すばる @SubaruG

仮に生成部分が動的に切り替わらない場合には、普通に別クラスに分けて、で必要に応じて type erasure を使う。

2010-08-18 20:58:07
Egtra (ysk-noh) @egtra

@SubaruG ああ、Image a; Image b = a;としたら、aとbは同一の実体を保持するということですか?ならありですね。

2010-08-18 21:01:22
普通のC++使い、銀天すばる @SubaruG

@egtra immutable じゃない場合にどうするかは難しいのですが。むしろ、その場合には const を指定できる shared_ptr の方が優れてるかもしれません。

2010-08-18 21:05:36
前へ 1 ・・ 3 4