私のライブラリでは、実装の詳細が気にならないきれいなパブリックAPIを公開したいと考えています。あなたがそれを持っているので、これらの細部は公共の領域にも漏れています:いくつかのクラスは、ライブラリの他の部分で使用される有効なパブリックメソッドを持っていますが、APIのユーザにとってあまり有用ではないので、それの一部である必要があります。公共のコードの簡単な例:C++ APIの設計:パブリックインターフェイスをクリアする
class Cookie;
class CookieJar {
public:
Cookie getCookie();
}
class CookieMonster {
public:
void feed(CookieJar cookieJar) {
while (isHungry()) {
cookieJar.getCookie();
}
}
bool isHungry();
}
CookieJar
のgetCookie()
方法はおそらくとにかくクッキーを好きではないライブラリの利用者に有用ではありません。しかし、それは与えられたときにそれ自身を供給するためにCookieMonster
によって使用されます。
この問題の解決に役立ついくつかのイディオムがあります。 Pimplイディオムはクラスのプライベートメンバーを隠すことを提供しますが、APIの一部ではないパブリックメソッドを隠すことはほとんどありません。それらを実装クラスに移すことも可能ですが、残りのライブラリを使用するためには直接アクセスする必要があります。このようなヘッダーは次のようになります。
class Cookie;
class CookieJarImpl;
class CookieJar {
public:
CookieJarImpl* getImplementation() {
return pimpl.get();
}
private:
std::unique_ptr<CookieJarImpl> pimpl;
}
あなたが本当にこれらのメソッドへのユーザーアクセスを防止する必要がある場合には便利ですが、それは単に迷惑だ場合、これはあまり役に立ちません。実際には、ユーザーがCookieJarImpl
の実装にアクセスできないため、新しいメソッドは最後のものよりも無駄になりました。
代替の方法は、インターフェイスを抽象基本クラスとして定義することです。これにより、公開APIの一部であることを明示的に制御できます。このインタフェースの実装には、ユーザがアクセスできないプライベートな詳細を含めることができます。注意すべきことは、結果としての仮想呼び出しがPimplイディオムよりもパフォーマンスに影響を与えることです。より洗練されたAPIの取引速度は、高性能ライブラリであるとされるものにとってあまり魅力的ではありません。
完全なものにするには、問題のあるメソッドをプライベートにして、外部からアクセスするために必要な場合にフレンドクラスを使用することもできます。ただし、これにより、ターゲットオブジェクトには本当にプライベートメンバーにアクセスできるようになり、カプセル化がやや壊れます。
これまでのところ、私にとって最善の解決策はPythonのやり方だと思われます。実装の詳細を隠そうとするのではなく、パブリックAPIの一部ではないと容易に識別でき、定期的な使用。頭に浮かぶ命名規則は、接頭辞のアンダースコアを使用していますが、明らかにそのような名前はコンパイラ用に予約されており、その使用は推奨されません。
ライブラリ以外から使用する予定のメンバーを区別するための他のC++命名規則はありますか?あるいは、上記の選択肢の1つ、または私が逃した何か他のものを使用するように私に提案しますか?
私は残りの部分はプライベートに、あなたは、エンドユーザーのパブリックから隠さたいメソッドを作ると思うし、あなたのAPIのニーズの残りの部分は、ちょうどの友人になるこれらのクラスを宣言し、今、民間のもののためにあなたのクラスはここですか? https://msdn.microsoft.com/en-us/library/465sdshe.aspx – Cody
このデザインアプローチが役立つかもしれません:http://stackoverflow.com/questions/27492132/how-can-i-remove-refactor-友人依存宣言 - 正しく –
@Cody私は私の質問でそのオプションを考慮しました。 2つのクラスは、私が見てきた多くのスタイルガイドによれば、ここで適切な友達を使用するのに十分に関連していません。 – Quinchilion