레거시 프레임 워크에서 작업 중입니다. 'A'는 기본 클래스이고 'B'는 파생 클래스입니다. 두 클래스 모두 중요한 프레임 워크 초기화를 수행합니다. FWIW는 ACE 라이브러리를 많이 사용합니다.파생 클래스 생성자 문제에 대한 종속성
나는 상황이있다; 'B'의 인스턴스가 생성됩니다. 그러나 'A'의 ctor는 'B'에서만 수행 할 수있는 초기화에 따라 달라집니다.
'B'가 인스턴스화되면 'A'에 대한 식별자가 'B'식별자 전에 호출됩니다. static functions
을 사용하는 virtual
메커니즘은 ctors에서 작동하지 않으므로 (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;
};
그러나 초기화 목록에 초기화 클래스 멤버는 아직 '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))
{ }
};
를 동일에 좀 더 설명은 m ++ c.l.c에 this 링크를 참조하십시오.. Konstantin Oznobikhin이 제시 한 멋진 일반적인 솔루션이 있습니다.
UB (정의되지 않은 동작) 및 컴파일러에서 재생하는 다소 괴로운 속임수입니다. –