2016-09-21 4 views
3

파생 클래스의 멤버 변수를 초기화하고 그 후에 기본 클래스 생성자에 전달하고 싶습니다. 아래 해결책을 생각해 냈습니다. (여기도 : http://cpp.sh/4uu4q)Initialize 기본 클래스 생성자를 호출하기 전에 파생 클래스 멤버 변수를 초기화합니다. 이 UB인가?

1) 다음 코드에 정의되거나 정의되지 않은 동작 (UB)이 있습니까?

2) 잘못된 디자인을 표시하려고합니까?

struct Data { 
    int fValue; 

    Data(int value = -1) : fValue(value) 
    {} 
}; 


struct Base { 
    Base(const std::unique_ptr<Data> & derivedData) { 
     std::cout << "Constructing Base derivedData=" << derivedData->fValue << std::endl; 
    } 
}; 


struct Derived : public Base { 
    std::unique_ptr<Data> fData = std::move(fData); 

    Derived() : Base(ConstructData()) 
    {} 

    const std::unique_ptr<Data> & ConstructData() { 
     fData.release(); 
     fData.reset(new Data(777)); 
     std::cout << "in ConstructData: fData->fValue =" << fData->fValue << std::endl; 
     return fData; 
    } 
}; 


int main() { 
    Derived d; 
    std::cout << "In main: d.fData->fValue =" << d.fData->fValue << std::endl; 
    return 0; 
} 
+0

2) 네, 기본 클래스가 생성자에서 파생 된 클래스에 대해 알아야하는 이유는 무엇입니까? – user463035818

+0

파생 클래스는 기본 클래스가 생성 될 때까지 생성되지 않습니다. 이것은 UB입니다. –

+0

생성자가 호출되기 전에 fData를 조작하므로 UB입니다. –

답변

3

나는 파생 클래스의 멤버 변수를 초기화, 그리고 그 후 기본 클래스 생성자에 전달할 것입니다.

C++에서 파생 부품보다 먼저 기본 파트가 구성됩니다. 왜냐하면 파생 된 부품이 기본 부품 측면에서 (잠재적으로) 구성되는 것이 훨씬 더 일반적이기 때문입니다. 이를 잘 정의하기 위해 기본이면서 파생 된 순서가 지정됩니다. 따라서 기지에서 유도 된 사용은 정의되지 않습니다.

기초에서 파생 멤버를 사용하려면 순서가 맞는지 확인하는 방법이 있습니다. "멤버"도 기본 클래스로 만듭니다. boost::base_from_member은이 기능을보다 편리하게 구현할 수 있도록 제작되었습니다.

는 일부

class member_type{}; 

이 있고 derivedmember_type 멤버가 있고, base에서 파생이하고 싶은 말. 그럼 당신은 사용할 수 있습니다

class derived : 
    private boost::base_from_member<member_type>, 
    public base { 
    using my_member_type = private boost::base_from_member<member_type>; 

public: 
    derived(); 
}; 

참고 이제 derived 서브 클래스 모두 my_member_typebase (순서대로). 따라서 후자는 전자를 건설에 사용할 수 있습니다.

derived::derived() : 
    my_member_type{3}, 
    base{my_member_type::member} { 
}