2016년 3월 22일 화요일

[c++] 순수가상클래스와 인터페이스의 차이점

오랜만에 C++ 코딩을 하느라 정신이 없습니다. 그런 와중에도 한가지 적을만한 내용이 있어서 적어봅니다.

C++ 에는 아시다 시피 interface 라는 것이 컴파일러 차원에서 재공되지 않습니다. Java 에서는 interface 라는 키워드도 있고
interface 구현 할때는 내부 구현을 못하도록 강제로 막아 주기도 하지요. 디자인 적인 차원에서 매우 훌륭한 특징이라고 생각합니다.

대신에
C++ 에서는 Abstract class 라는 것을 지원하는데 구현 함수중의 적어도 한개를 virtual 로 선언하고 구현을 Null 값으로 할당해서 구현을 비워두면 자동으로 추상 클래스가 됩니다. Java 의 interface 와의 차이점은, Java 에서는 내부 구현을 전혀 못하도록 강제하는 반면에  C++ 에서는 일부 구현을 허용한다는 점이 다릅니다.

그러면 C++ 의 추상 클래스를 사용해서 Java 의 interface 와 완전히 똑같은 것을 사용하려면 어떻게 해야하는가? 하는 것이 사실 이 글의 요점입니다.
컴파일러의 도움없이 수작업으로 모든 함수들을 공란으로 비워두면 interface 와 비슷해지지만, 완전히 같아지지는 않습니다. 문제는 C++ 에서는 interface 같은 형태로 사용하려면 다중 상속의 개념이 적용되는데 C++ 에서 상속을 할때에는 반듯이 소멸자가 virtual 로 선언되어야 합니다. 그런데 소멸자는 선언이 되면 반듯이 구현도 같이 해줘야 하는 문제가 덩달아 생겨납니다.

그래서 아무리 비슷하게 하려고 해도 아래와 같이 소멸자는 구현이 되어야 한다는 것입니다.

class EventListener {
public:
    virtual ~EventListener() {} // 이 부분이 구현이 된 것입니다.

    virtual void handleEvent(EventPtr evt) = 0; // 함수를 virtual 로 선언하고 구현을 비워둡니다.
};
그래서 결론은 비슷하게 사용할수 있지만 interface 인 녀석이 구현을 담고 있다는 것이 여전히 꺼림직 합니다.

소멸자는 순수 가상함수로 선언할수 없습니다. 

추가로(참고 : http://pacs.tistory.com/35)
class EventListener {

public:
   virtual ~EventListener() = 0; // 순수 가상 소멸자의 선언. 이렇게 수행할 수 없는게 아니다.

};
 EventListener::~ EventListener() {} //순수 가상 소멸자의 선언. 다만 순수 가상소멸자는 반드시 정의를 해 두어야 하기에 위의 예제와같이 작성한다.

댓글 없음:

댓글 쓰기

[Effective C++] 항목 30 : 인라인 함수는 미주알고주알 따져서 이해해 두자.

인라인 함수를 사용하면 컴파일러가 함수 본문에 대해 문맥별 최적화를 걸기가 용이해집니다. 인라인 함수의 아이디어는  함수 호출문을 그 함수의 본문으로 바꿔치기하자는 것  남발했다가는 코드의 크기가 커질 게 뻔하다. 인라인 함수로 부풀려진 ...