C and C++

[C++] 상속에 대해

개발새발 2018. 9. 1. 13:36
반응형

Java나 C#과는 다르게 C++는 다중 상속도 가능하며(권장 하지는 않지만) 상속자체에도 접근제한을 둘 수가 있다. 이러한 점이 다른 객체지향 언어보다 혼란스러운 이유이다.

하지만 C++에서 상속관계를 고려할 때 Java나 C#의 방식과 비슷하게 상속관계를 생각해도 된다. 

즉, 다중상속을 사용하지 않고 상속의 접근 제한자는 public 상속만 사용하겠다고 마음먹는 편이 편하다.


나 혼자 개발하면 위와 같이 생각하면 편하지만 여러 개발자랑 개발해야 하는 경우가 더 많기 때문에 여러가지 상속에 대해서도 알아둘 필요가 있어보인다.

사실 다중상속은 경험이 부족해서인지 아직까지 실제로 쓰이는 것을 본적은 없다.


그나마  HAS-A 관계를 구현할 때 객체합성을 이용하거나 private 상속을 이용하는 경우가 있다. 일단 객체합성과 private 상속을 비교하기전에 private상속과 public 상속은 뭐가 다른지에 대해 정리해보자.


Private 상속 VS Public 상속

객치제향 상속에 대해 설명할 때 항상 교과서적으로 나오는 말이 바로 IS-A관계이다. C++에서 public상속의 경우 100% IS-A관계가 성립하지만 private상속의 경우 성립되지 않는다. Effective C++ 을 보면 is-implemented-in-terms-of 관계라고 설명한다. 즉, 그 객체를 사용해서 구현하는 의미로 HAS-A관계와 더 가깝다. 따라서 private상속은 문법적으로는 상속이지만 실제 내용은 상속과는 관계가 거의 없다고 볼 수 있다.(다형성의 장점을 쓸 수 없기때문에) 

Private 상속 VS 객체 합성

객체합성을 쓰지 않고 private상속을 사용하는 경우를 생각해보자. 거의 사용 되지 않지만 다음과 같은경우 사용된다.
활용하고자 하는 객체의 가상 함수를 재정의 하고 싶을 때 private상속을 사용하면 된다.

[private상속 예 (예가 적절하지 않을 수도 있다.)]

class Engine {

public:

    void stop() {

        cout<<"멈춤"<<endl;

    }

    

    virtual void start() {

        cout<<"일반 엔진"<<endl;

    }

};


class SuperCar : private Engine {//is-implemented-in-terms-of 관계 객체 합성과 거의 유사

private:

    virtual void start() { //override 가능!

        cout<<"슈퍼 엔진"<<endl;

    }

public:

    void superStart() {

        start();

    }

    

    void stop() {

        Engine::stop();

    }

};



위의 코드를 객체 합성으로 바꾸어 보면 다음과 같다.

[객체 합성 예]

class SuperCar {

private:

    Engine superEngine; //객체 합성


public:

    void superStart() {

        superEngine.start(); //override 불가!

    }

    

    void stop() {

        superEngine.stop();

    }

};


반응형