11

いくつかの異なるクライアントに提供する C++ ライブラリがあります。最近、パブリック インターフェイスで生のポインターを使用することから、代わりに boost::sharedptr を使用するように切り替えました。ご想像のとおり、これにより、クライアントは誰が何をいつ削除する必要があるかを心配する必要がなくなるという点で、非常に大きなメリットがもたらされました。切り替えを行ったとき、私はそれが正しいことだと信じていましたが、公開インターフェイスにサードパーティのライブラリから何かを含める必要があることに悩まされていました。通常、そのようなことはできれば避けま​​す。私は、boost は事実上 C++ 言語の一部であり、私たちのユース ケースでは、クライアント コードとライブラリの両方がオブジェクトへのポインターを保持する必要があることを合理化しました。しかし最近、クライアントの 1 人から、インターフェイスでニュートラル スマート ポインター クラスを使用するように切り替えることができるかどうか尋ねられました。私たちのライブラリは基本的に特定のバージョンのブーストを強制しているためです。では、どうするのが最善策なのか、今考えています。私はそれについて少し考え、実際のブースト スマート ポインターを単に保持する単純なスマート ポインター クラスを作成することについて疑問に思いました。しかし、クライアントはすぐにそれらの 1 つを自分たちのフレーバーの boost::sharedptr に詰め込み、3 つの共有ポインターの深さになります。これは問題になる場合もあれば、そうでない場合もあります。とにかく、この問題を解決する最善の方法についてコミュニティから意見を聞きたいです。私はそれについて少し考え、実際のブースト スマート ポインターを単に保持する単純なスマート ポインター クラスを作成することについて疑問に思いました。しかし、クライアントはすぐにそれらの 1 つを自分たちのフレーバーの boost::sharedptr に詰め込み、3 つの共有ポインターの深さになります。これは問題になる場合もあれば、そうでない場合もあります。とにかく、この問題を解決する最善の方法についてコミュニティから意見を聞きたいです。私はそれについて少し考え、実際のブースト スマート ポインターを単に保持する単純なスマート ポインター クラスを作成することについて疑問に思いました。しかし、クライアントはすぐにそれらの 1 つを自分たちのフレーバーの boost::sharedptr に詰め込み、3 つの共有ポインターの深さになります。これは問題になる場合もあれば、そうでない場合もあります。とにかく、この問題を解決する最善の方法についてコミュニティから意見を聞きたいです。

編集: 私はもともと所有権の譲渡を言いましたが、API 境界の両側のコードがオブジェクトへのポインターを保持する必要があることを指定する必要がありました。

4

10 に答える 10

18

考えられる解決策の1つは、boost::shared_ptrをプロジェクトに同梱することです。すべてヘッダーで構成されているため、これにより、クライアントはBoostライブラリを手動でインストールする必要がなくなります。bcpを使用して、ライブラリ自体を含む、特定のBoostライブラリに必要なすべてのファイルを取得できます。私は当時会社で働いていて必要だったときにそれをしました、boost::shared_ptrそしてそれは実際に大いに働きました。

于 2008-12-02T21:07:08.310 に答える
13

TR1 のリリース時点で、shared_ptr<>は言語の一部です。参照: (TR1)

于 2008-12-02T20:46:19.630 に答える
6

まず、ライブラリをコンパイル済みライブラリとしてではなくソースコードとして配布する場合は、この回答を無視できます。他のプラットフォームには関係がないかもしれないいくつかのウィンドウ固有の問題もあります。

個人的には、ライブラリのパブリックインターフェイスにファンキーなc ++を入れすぎないようにする必要があると思います。これは、クライアントで多くの問題を引き起こす可能性があるためです。

これがあなたの特定の例にどれほど当てはまるかはわかりませんが、新しいバージョンにアップグレードしたときに、使用したstlライブラリのシンボルがサードパーティライブラリのシンボルと競合するという問題に個人的に遭遇しました。これは、奇妙な場所でクラッシュが発生したことを意味し、問題を回避するために多くのトリックを実行する必要がありました。結局、私はこのために古いバージョンのライブラリを使い続けました。

遭遇する可能性のある別の問題は、異なるc ++コンパイラが同じシンボルを異なる方法でマングルする可能性があることです。つまり、同じBoostバージョンを使用している場合でも、サポートするコンパイラごとに個別のライブラリを提供する必要があります。これに関する議論については、本「ImperfectC++」をチェックしてください。

さまざまなC++コンパイラと環境の現在の世界では、悲しい真実は、インターフェイスにC以外のものを含めないようにし、ライブラリを動的にリンクするようにする必要があることだと思います(顧客をリンクするときの競合を避けるために、ライブラリ、Windowsランタイムライブラリをリンクしますここでは本当に苦痛になる可能性があります)。すべてのシンボルがdll内の顧客環境から分離されるため、ライブラリ内でブーストとファンシーなc++を必要なだけ使用できます。

ライブラリのインターフェイスにスマートポインタやその他の優れたC++機能が本当に必要な場合は、ソースコードを配布するための便利なレイヤーを構築してください。これにより、常にお客様の環境でコンパイルされるようになります。次に、このインターフェイスは公開されたC関数を巧妙な方法で呼び出します。そのレイヤーでブーストを使用するのは良い考えではないと思います。それは、顧客が望まない場合でもブーストを採用することを余儀なくされるためです。ただし、そのレイヤーはソースとして配布されるため、簡単に交換したり、別のソリューションを見つけたりできます。コード。

もう1つの優れた機能は、ライブラリをC / C ++以外の言語に公開する場合、奇妙な名前のマ​​ングリングを持つc++関数よりもdllでC関数を呼び出す方が一般的に簡単なことです。

このアプローチは確かに多くの点であなたの人生をより複雑にしますが、それは彼ら自身のコードとうまくリンクすることができなかったので人々があなたのライブラリを避ける可能性を少なくする方法です。

于 2008-12-02T22:13:09.457 に答える
6

セマンティクスが本当に所有権の譲渡である場合、標準 C++ であるため auto_ptr を使用しないのはなぜですか? 内部的には、引き続き auto_ptr から shared_ptr を構築し、必要に応じて所有権を共有できます。

于 2008-12-02T20:40:37.023 に答える
4

これは C++ です。ご存知のように、共有ポインターの実装を介してインターフェイス クラスをテンプレート化できます。

于 2008-12-02T20:36:57.623 に答える
3

ブーストコピーユーティリティを使用して、スマートポインタクラスのみを持つカスタムバージョンのブーストを構築できます。スマートポインタクラスはヘッダーのみのライブラリであるため、これにより、ライブラリに含めることができるいくつかのヘッダーが作成されます。

于 2008-12-02T21:06:03.990 に答える
3

これは私がしばらく前から抱いていた興味深い質問です。提供するライブラリをユーザーに強制しますか、それともプロジェクトで何が最適かをユーザーに決定させますか? いつものように、問題はあなたが何を提供しているか、ユーザーに何を求めているかです。

生のポインターを使用すると、あらゆる種類の可能性が可能になります。ユーザー コードは生のポインターを使用して、それを std::auto_ptr、shared_ptr (boost または TR1)、または自作バージョンのスマート ポインターに格納できます。しかし、これはユーザーがメモリを解放するのを忘れた場合にも問題を引き起こす可能性があり、メソッド呼び出し用に作成された一時的なものだけが必要な場合は、ユーザー側でさらにコードが必要になります (生のポインターを提供する場合は、非一時的な [おそらくスマートな] ポインター変数内のポインター)。

ここで、スマート ポインターを使用すると、ソリューションがユーザーに強制されます。彼らが独自のバージョンのスマート ポインターを使用することを計画している場合 (たとえば、boost::shared_ptr を使用していて、std::tr1::shared_ptr が必要な場合)、インターフェイスで動作する場合は使用できなくなります。どのようなスマート ポインターを決定しても (特別な std::auto_ptr を除いて)、解決策を強制するだけでなく、それが持つ問題も強制されます。

ユーザーがマルチスレッド アプリケーションを使用していて、ソリューションがスレッド セーフでない場合、ユーザーは安全でないソリューションにバインドされます。一方、スマート ポインターがスレッド セーフであるがロック コストが発生する場合、ユーザーがマルチスレッド アプリケーションで作業している場合でも、それらのコストがユーザーに押し付けられます。ライブラリ (ヘッダーのみのライブラリではない) をコンパイルすると、スマート ポインターの種類だけでなく、スマート ポインターの特定のバージョンも強制されます。これは、スマート ポインター ライブラリを変更すると、コードの互換性が失われるためです。

補足として、boost::shared_ptr (boost 1.33+) はほとんどの状況でスレッドセーフであり、多くのプラットフォームでロックフリーの実装を使用しています。とにかく、これはあなたが考慮すべきことのアイデアを与えるはずです.

最後に、ユーザーが特定のタイプのスマート ポインターを使用するようにバインドしているだけでなく、同じバージョンのスマート ポインターも使用していることを考慮する必要があります。lib を特定のバージョンの boost に対してコンパイルすると、ユーザーはその特定の実装にバインドされます o

于 2008-12-02T21:43:11.200 に答える
2

boost::intrusive_ptrおそらく?

于 2008-12-02T20:40:25.743 に答える
1

C インターフェイスを使用auto_ptrまたは固執します。C++ ライブラリをインターフェイスに強制することは常に見苦しく、クロスプラットフォームになる可能性をなくし、さまざまな「ダウンストリーム」構成を持つ顧客にメンテナンスの悪夢を引き起こします。

クライアントにとって C++0x が十分に主流になったら、すぐに に切り替えてくださいstd::shared_ptr

于 2010-07-22T02:36:06.837 に答える
1

boost::shared_ptr を導入すると、クライアントはブーストを使用するようになります。一部の人々にとって、これは小さな問題です。

また、ライブラリがコンパイル済みバイナリとして配布されている場合、クライアントはライブラリで使用されているものと同じコンパイラを使用する必要があります。または、ライブラリがソース コードで配布されている場合、クライアントは、ライブラリのコンパイルに使用される独自のコンパイラの選択に固執する必要があります。これは、かなりの規模のプロジェクトにとって小さな問題ではありません。

于 2010-07-22T02:27:29.057 に答える