私はレガシーフレームワークに取り組んでいます。「A」が基本クラスで「B」が派生クラスだとしましょう。どちらのクラスも、いくつかの重要なフレームワークの初期化を行います。FWIW、それはACEライブラリを多用しています。
私には次のような状況があります。「B」のインスタンスが作成されます。しかし、「A」の ctor は、「B」からのみ実行できるいくつかの初期化に依存しています。
'B' がインスタンス化されると、'A' の ctor が 'B' の ctor の前に呼び出されます。このvirtual
メカニズムは ctors からは機能しません。使用static functions
は除外されています ( static-initialization-order- fiasco のため)。
次のようにCRTPパターンを使用することを検討しました:-
template<class Derived>
class A {
public:
A(){
static_cast<Derived*>(this)->fun();
}
};
class B : public A<B> {
public:
B() : a(0) {
a = 10;
}
void fun() { std::cout << "Init Function, Variable a = " << a << std::endl; }
private:
int a;
};
しかし、イニシャライザ リストで初期化されたクラス メンバは、まだ実行されていないため、未定義の値を持ちます (上記の場合は fe 'a')。私の場合、そのようなフレームワークベースの初期化変数が多数あります。
この状況を処理するためのよく知られたパターンはありますか?
前もって感謝します、
更新:
dribeas から提供されたアイデアに基づいて、この問題に対する一時的な解決策を思いつきました (本格的なリファクタリングは、今のところ私のタイムラインには合いません)。次のコードは同じことを示します:-
// move all A's dependent data in 'B' to a new class 'C'.
class C {
public:
C() : a(10)
{ }
int getA() { return a; }
private:
int a;
};
// enhance class A's ctor with a pointer to the newly split class
class A {
public:
A(C* cptr)
{
std::cout << "O.K. B's Init Data From C:- " << cptr->getA() <<
std::endl;
}
};
// now modify the actual derived class 'B' as follows
class B : public C, public A {
public:
B()
: A(static_cast<C*>(this))
{ }
};
同じことの詳細については、clc++.m のこのリンクを参照してください。Konstantin Oznobikhin によって提供された優れた一般的な解決策があります。