상송은 사실 함수 인터페이스 상속과 함수 구현 상속 이렇게 두 가지로 나뉩니다. 멤버 함수 인터페이스는 항상 상속된다. 하지만 구현에 대해서는 상속 여부가 3가지로 나뉜다.
* 순수 가상 함수는 인터페이스 상속만을 허용합니다.
virtual void func() = 0;
와 같이 = 0; 붙이는 것을 순수 가상 함수라고 한다. 순수 가상함수의 특징은 두가지가 있다. 첫째, 어떤 순수 가상 함수를 물려받은 구체 클래스가 해당 순수 가상 함수를 다시 선언해야 한다. 둘째, 순수 가상 함수는 전형적으로 추상 클래스 안에서 정의를 갖지 않는다.
* 단순(비순수) 가상 함수는 인터페이스 상속과 더불어 기본 구현의 상속도 가능하도록 지정합니다.
virtual 을 앞에 붙이고 함수 구현까지도 정의를 한 것을 단순 가상 함수라고 부른다.
단순 가상 함수에는 주의해야할 사항이 있다.
class Airplane { public: virrual void fly(); }; void Airplane::fly() { 기본적인 날라가는 동작 } class Model_A : public Airplane { ... }; class Model_B : public Airplane { ... };
만약 Model A, B는 기본적인 날라가는 동작으로 비행을 하지만, 추후 새롭게 추가되는 Model_C에서는 다른 방법으로 날라가는 동작을 구현해야 하는 경우, 위의 Code는 Model_C에서 fly()를 override 하지 않아도 compile에 아무런 error를 발생시키지 않는다.
간단한 방법으로는 가상 함수의 인터페이스와 그 가상 함수의 기본 구현을 잇는 연결 관계를 끊어버리는 것이다.
class Airplane { public: virrual void fly() = 0; protected: void defaultFly(); }; void Airplane::defaultFly() { 기본적인 날라가는 동작 } class Model_A : public Airplane { public: virtual void fly() { defaultFly(); } }; class Model_B : public Airplane { public: virtual void fly() { defaultFly(); } };
여기서 주의점은 defaultFly()는 비가상 함수라는 점이다. 이 동작이 재정의 되어서는 안되기 때문이다. 하지만 이런식의 구현을 좋아하지 않는 사람이 있다. 그럴 경우 순수 가상 함수가 구체 파생 클래스에서 재선언되어야 한다는 사실을 활용하되, 자체적으로 순수 가상 함수의 구현을 구비해 두는 방법도 있다.
class Airplane { public: virrual void fly() = 0; }; void Airplane::fly() { 기본적인 날라가는 동작 } class Model_A : public Airplane { public: virtual void fly() { Airplane::fly(); } }; class Model_B : public Airplane { public: virtual void fly() { Airplane::fly(); } };
별도의 함수이름을 만들지 않아도 되어서 좋긴하지만, 앞의 경우는 두 함수에 각기 다른 보호 수준 부여가 가능했지만, 이 경우는 그런 융통성은 없다.
* 비가상 함수는 인터페이스 상속과 더불어 필수 구현의 상속도 가하도록 지정합니다.
클래스 파생에 상관없이 변하지 않는 동작 및 필수적인 구현(mandatory implementation) 을 지정하는데 쓰인다.
멤버 함수를 선언 할때 가장 흔히 발견되는 실수 두 가지 정도는 피해줬으면 한다.
첫째, 모든 멤버 함수를 비가상 함수로 선언하는 것이다. 가상 함수가 실행시 성능에 안좋다고 생각하는 사람들이 안타까울 정도로 많은데 80-20 법칙을 기억해라. 전체 실행 시간의 80%가 소모되는 부분은 전체 코드의 20% 밖에 되지 않는다. 정말 특수한 상황이 아니면 함수 중 80%를 가상함수로 두어도 수행 성능에는 영향을 거의 미치지 않는다.
둘째 모든 멤버 함수를 가상으로 선언하는 것이다. 클래스 파생에 상관없는 불변동작을 갇고 있어야 한다면 비가상으로 선언해라.
댓글 없음:
댓글 쓰기