Base
type のデフォルト パラメータ値を持つクラスの静的メソッドが必要ですDerived
。オーバーロードを使用せずにこれを実装する方法はありますか? (ここを参照)。
class Base;
class Derived;
Derived make_derived(void);
class Base
{
public:
static void problem_here(Base && = make_derived());
};
class Derived : public Base
{
};
Derived make_derived()
{
return Derived();
}
... incomplete type の使用に関するエラーが表示されますDerived
。ただし、基本クラスの定義の後に定義する必要があるため、の定義をDerived
前に配置することはできません。problem_here
Base
残念ながら、からポインターを返すことmake_derived
はできません。
problem_here
今まで思いついたのはオーバーロードだけですが、「実際の」problem_here
メソッドは2つ(および別の3つ)のパラメーターを取り、それはライブラリの一部であるため、これにより...
static void problem_here(Thing const &, Base const &);
static void problem_here(Thing const &, Base &&);
static void problem_here(Thing const &); // Default param "hack"
static void problem_here(Thing &&, Base const &);
static void problem_here(Thing &&, Base &&);
static void problem_here(Thing &&); // Default param "hack"
.. 2 つのパラメーターの場合のみ。
同じパフォーマンス (パラメーター コンスタレーションの不要なコピー/移動構築がない) と呼び出し元サイトでの同じ動作を維持しながら、これらすべての関数シグネチャを記述することを回避する方法はありますか?
problem_here
のような複数の関数があり、すべての保護されたコンストラクターDerived
(およびその多くの兄弟のコンストラクター) にアクセスする必要があることを追加する必要があります。したがって、これらのメソッドを Base の静的メンバーにする主な理由はfriend class Base;
、すべての関数をフレンドシップするのではなく、各派生クラスでできるようにするためです。
リファクタリングにより、派生クラスの保護されたコンストラクターにアクセスするコードを単一のファクトリー関数に移動できることがわかりました。そうすれば、デフォルトのパラメーターを使用して関数を外部に移動しBase
、ファクトリーを呼び出すことができます。今でも、これらの関数のすべてをフレンドリにする必要がありますが、(Base
ファクトリへのアクセスを許可するために) 1 回だけです。すべての関数をヘルパー クラスに配置し、代わりにそれをフレンドにすることでこれを回避できますが、それは私にはハックのように見えます。
class Base
{
friend class Helper; // The Hack
friend void no_problem_here(Base &&); // No hack, more writting
protected:
static void factory(Thing && from_which_I_can_construct_the_correct_derived_class);
// return type void to keep it simple, move parameter type because special cases
// handled in "trampoline" functions and a copy of the Thing must be stored either
// way.
};
class Derived : public Base
{
friend class Base;
// protected constructor omited for simplicity.
}
void no_problem_here(Base && = make_derived());
// ...
void no_problem_here(Base && b)
{
// work, and then call Base::factory
}
// or
class Helper
{
protected:
// Constructors ...
public:
static void no_problem_either(Base && = make_derived());
};