'상속막기'에 해당되는 글 1건

  1. 2011.05.31 상속을 막는 방법.
2011.05.31 10:09
C++에서는 자바의 final(?이거였나ㅡㅡ;;) 처럼 상속을 막는 기능을 제공하지 않는다.
그래서 컴파일 에러를 이용해 상속을 막는다.!
가장 쉽게 생각할 수 있는 방법은 부모의 생성자를 private영역에 두어 상속을 막는 방법이 있다.
하지만 이렇게 만들경우 부모 클래스의 임시 객체, 전역객체 역시 생성을 못한다는 단점이 있다.

그래서 아래와 같은 방법을 이용한다.

첫번째. friend와 virtual상속을 이용.
class NonInheritance
{
    friend class Test;
private :
    NonInheritance(){}
    NonInheritance( const NonInheritance& _other ) {}
};

class Test : public virtual NonInheritance
{
public :
   Test(){}
};

class TestEx : public Test
{
public :
   TestEx(){}  // 컴파일 에러 발생.!
};

friend 키워드를 이용해 Test 클래스는 NonInheritance 클래스의 private영역에 접근이 가능하다.
그러나 TestEx클래스는 NonInheritance 클래스의 생성자에 접근이 불가능하므로
이를 이용해 상속을 막을 수 있다.
(상속을 막을 수있는 좀더 자세한 원리는 virtual 키워드에 있는데 이는 아래쪽에서 설명한다.)

#첫 번째 방법을 매크로 함수를 이용해 좀 더 사용하기 쉽게 만들 수 있다.

--
#define NonInheritance(x) \
class x; \
class __NonInheritance##x \
{ \
   friend class x; \
private: \
     __NonInheritance##x() {} \
     __NonInheritance##x(const __NonInheritance##x&) {} \
}
#define NonInheritanceSuper(x)    public virtual __NonInheritance##x 


NonInheritance(Test);
class Test : NonInheritanceSuper(Test)
{ ... };
-- 
 

두번째. 좀더 간단하게 virtual을 이용.
class NonInheritance
{

protected:
    NonInheritance(){}
    NonInheritance( const NonInheritance& _other ) {}
};

class Test : private virtual NonInheritance
{
public :
   Test(){}
};

class TestEx : public Test
{
public :
   TestEx(){}  // 컴파일 에러 발생.!
};

friend 키워드를 사용하지 않고 NonInheritance의 생성자를 protected로 만든다.
그리고 private virtual 상속을 이용한다. Test클래스는 NonInheritance의 생성자에 접근이 가능하지만
역시 TestEx클래스에서는 접근이 불가능하다.

# virtual 상속의 원리.(내가 이해한 부분. 틀릴수도 있다...ㅜㅠ)

상속을 막기위해 virtual 상속을 이용 하였는데, 이는 다중상속에 사용되는 virtual 키워드의 원리를 이용한 것이다. 
다중 상속에서는 C++문법에 예외를 몇가지 두는데 그 중 하나가 바로 상속 계층의 최하위 클래스에서 
최상위 클래스의 초기화를 전담해야한다는 것이다.(이는 자식 클래스는 바로 위의 부모클래스의 생성자만을 호출 할 수 있다는 C++문법의 예외가 된다.) 또하나는 Test클래스가 직접 NonInheritance클래스의 멤버를 포함하지 않는다는 것이다.
아무튼 이러한 다중상속시 문법예외를 통해 상속을 막는 것이다.
(상속시 virtual 키워드가 사용되면 컴파일러는 이를 다중상속의 관계로 인식 하는듯 하다.)

즉, 정리 하자면 아래와 같나??ㅋ
가상상속시에 최하위 클래스(TestEx)가 최상위 클래스(NonInheritance)의 생성을 전담하게되는데,
이때 최상위 클래스(NonInheritance)의 생성자가 public이면 외부에서 모부 접근가능하므로 중간 클래스(Test)가 부모클래스를 private로 상속을 받아도 TestEx에서 최상위클래스의 생성자로 접근이 가능하다!

하지만 NonInheritance의 생성자가 protected일 경우에 TestEx가 직접 NonInheritance를 상속받는게 아니므로, (가상상속시 TestEx가 Test의 생성자를 거쳐 NonInheritance의 생성자를 호출하지 않으므로)
신고
Posted by 우엉 여왕님!! ghostkyow

티스토리 툴바