프로그래밍 일반 2014. 4. 10. 17:26

C++ 11 생성자 상속 ( Inheriting Constructors )

웹 컴파일러 링크 : http://melpon.org/wandbox/


class CBase

{

public :    

    void Func(float f) {}  

};



class CDerived : public CBase

{

public :    

    void Func(int i) {}

};    


CBase bObj;

bObj.Func(3.1f); // Func(float f)

    

CDerived dObj;

dObj.Func(3.1f); // Func(int i) 호출 narrowing 발생



C++ 98 에서 아래 코드는 베이스 클래스로 부터 파생 클래스로 오버로딩 된 함수들을 옮길 수 있다.



class CBase

{

public :    

    void Func(float f) {}  

};



class CDerived : public CBase

{

public :

    using CBase::Func;

    void Func(int i) {}

};


CBase bObj;

bObj.Func(3.1f); // Func(float f)

    

CDerived dObj;

dObj.Func(3.1f); // CBase::Func(float f) 호출


C++ 11 에서는 멤버 함수 뿐만 아니라 생성자들에도 이러한 기능을 사용할 수 있다.


class CDerived : public CBase

{

public :

    using CBase::CBase; // 베이스의 생성자를 파생 클래스 범위로 가져온다. C++ 11 에서만 가능

    CDerived(int i) {} // 이 생성자를 CBase::CBase(int i) 보다 선호한다.

    

    using CBase::Func; // 베이스의 Func를 파생 클래스의 범위로 가져온다. C++ 98 작동

    void Func(int i) {}

    void Func(char c) {}

    void Func(float f) {} // 이 Func 를 CBase::Func(float) 보다 선호한다.

    

private :

    int m_iValue;

};      





class CBase

{

public :

    CBase(int iValue = 0) {}

    

    void Func(float f) {}  

};



class CDerived : public CBase

{

public :

    using CBase::CBase; // 암시적으로 CDerived(int = 0) 선언

    

    using CBase::Func;

    void Func(int i) {}

    void Func(char c) {}

    

private :

    int m_iValue;

};        




int main()

{

    CBase bObj(10);

    bObj.Func(3.1f); // Func(float f)

    

    CDerived dObj(10); // 생성된다.

// dObj.m_iValue 가 초기화되지 않는다.

// 파생 클래스에서 베이스 클래스의 생성자를 상속할 때, 파생 클래스에서 새로운 멤버 변수를 

// 초기화해야 한다면 이런 실수가 가능하다.

    

    return 1;

}


위와 같은 문제는 멤버 초기화자 ( member initializer ) 를 이용하여 해결한다.


class CDerived : public CBase

{

public :

    using CBase::CBase;

    

    // ....

    

private :

    int m_iValue{0};

};



 CDerived dObj(10); // 생성되고 dObj.m_iValue 는 0