これらの「関数」がクラスのメンバーであるかどうかについては言及していませんが、そうであると仮定します。もしそうなら、「pimpl idiom」を見ることをお勧めします。基本的にこれは、非公開にしたいもののすべてまたはほとんどを別のクラスに入れ、クラス宣言でクラスのインスタンスへのポインターのみを持つことを意味します。例えば:
class MyClass
{
// ... some stuff
private:
SecretObject obj_;
int hiddenCall();
};
になる
class MyClassImpl;
class MyClass
{
private:
MyClassImpl* impl_;
};
アイデアは、実装クラスのすべての宣言と定義が .cpp ファイルに入り、コンパイル単位以外から隠されるということです。このアプローチには、多くの重要な利点があります。
- 実装を非表示にして、公開されているヘッダーが実装の多くを提供しないようにします。
- ヘッダーの依存関係を削除することでコンパイル速度を上げることができます - v. ヘッダーが多く含まれている場合は重要です。
- データベース API などに対してビルドする必要のないライブラリに対して、クライアント コードを「隔離」するのに役立ちます。
いくつかの欠点があります。
- コードが cpp ファイルに隠されている場合、単体テストがより難しくなる可能性があります。個人的には、コードのクライアントが取得するものを制御できるように、個別のプライベート ヘッダーと実装ファイルを用意し、テスト ハーネスで適切にテストすることがより良い解決策だと思います。
MyClassImpl
cpp ファイルにヘッダーを単純に含めることができますが、ヘッダーに含めないでくださいMyClass
。これにより、オブジェクトが無効になります。
- との間の間接性は
MyClass
、MyClassImpl
コーディングや管理が面倒になる可能性があります。
ただし、一般的には、目的を達成するためのおそらく最良の方法です。より詳細な説明については、Herb Sutter の記事を参照してください。
一方、クラスに直接関係のないfree functionsについて話している場合は、これらを cpp ファイル内の名前のない名前空間に配置します。例えば:
namespace {
// Your stuff goes here.
};
繰り返しますが、このアプローチを採用した場合にこれらの関数にアクセスする方法の単体テストの問題がありますが、それが本当に問題である場合は、おそらく特定の名前空間や条件付きコンパイルなどを作成することで、これを回避することができます。理想的ではありませんが、可能。