독서노트Effective_C++_조항 34: 인터페이스 계승과 실현 계승 구분

8716 단어 effective
이 조항서에는 내용이 비교적 많지만 사실 사상은 결코 복잡하지 않다.세 마디만 이해하면 된다. 첫 번째 말은 순허함수는 인터페이스만 계승한다.두 번째 말은 허함수는 인터페이스를 계승할 뿐만 아니라 기본적인 실현도 제공한다.세 번째 말은 일반 함수는 인터페이스를 계승할 뿐만 아니라 강제적으로 계승하여 실현한다는 것이다.여기서 토론의 구성원 함수는 모두public라고 가정합니다.
 
이 세 가지 함수를 살펴보면 다음과 같습니다.
1 class BaseClass
2 {
3 public:
4     void virtual PureVirtualFunction() = 0; //     
5     void virtual ImpureVirtualFunction(); //    
6     void CommonFunciton(); //     
7 }; 

순허함수는'0과 같다'는 성명이 있는데 구체적인 실현은 일반적으로 파생에 놓여 있다(단 기류도 구체적으로 실현될 수 있다). 존재하는 클래스(허기류라고 부른다)는 대상을 정의할 수 없다. 파생류에서도 이 순허함수를 실현하지 않고 파생류의 파생류에 의해 실현될 수 있다. 한 가지 파생류가 실현될 때까지 이 파생류가 그 대상을 정의할 수 있다.
허함수는 반드시 실현되어야 한다. 그렇지 않으면 링크 오류를 보고할 것이다.허함수는 기본 클래스와 여러 파생 클래스에서 서로 다른 버전을 제공할 수 있으며 다태적 성질을 이용하여 프로그램이 실행될 때 어떤 버전의 허함수를 실행할 것인지를 동태적으로 결정할 수 있다(메커니즘은 컴파일러가 생성한 허표이다).가상 키워드는 기본 클래스에서 명시적으로 명시해야 하며 파생 클래스에서는 명시할 필요가 없다. 쓰지 않아도 컴파일러가 가상 함수로 인정하고virtual 함수에 존재하는 클래스는 실례 대상을 정의할 수 있다.
일반 함수는 인터페이스와 실현을 모두 계승했다. 만약에 파생류에서 일반 함수를 다시 정의한다면 명칭의 커버(조항33 참조)가 나타날 것이다. 사실상 파생류에서 기본 함수를 덮어쓰는 일반 함수를 극히 추천하지 않는다. 만약 정말 이렇게 하려면 기본 함수를 허함수나 순허함수로 성명해야 하는지 반드시 고려해야 한다.
 
다음은 세 가지 유형의 구성원 함수 적용입니다.
 1 class BaseClass
 2 {
 3 public:
 4     void virtual PureVirtualFunction() = 0; //     
 5     void virtual ImpureVirtualFunction(); //    
 6     void CommonFunciton(); //     
 7 }; 
 8 void BaseClass::PureVirtualFunction()
 9 {
10     cout << "Base PureVirtualFunction" << endl;
11 }
12 void BaseClass::ImpureVirtualFunction()
13 {
14     cout << "Base ImpureVirtualFunciton" << endl;
15 }
16 
17 class DerivedClass1: public BaseClass
18 {
19     void PureVirtualFunction()
20     {
21         cout << "DerivedClass1 PureVirturalFunction Called" << endl;
22     }
23 };
24 
25 class DerivedClass2: public BaseClass
26 {
27     void PureVirtualFunction()
28     {
29         cout << "DerivedClass2 PureVirturalFunction Called" << endl;
30     }
31 };
32 
33 int main()
34 {
35     BaseClass *b1 = new DerivedClass1();
36     BaseClass *b2 = new DerivedClass2();
37     b1->PureVirtualFunction(); //     DerivedClass1   PureVirtualFunction
38     b2->PureVirtualFunction(); //     DerivedClass2   PureVirtualFunction
39     b1->BaseClass::PureVirtualFunction(); //        BaseClass   PureVirtualFucntion
40     return 0;
41 }

책에서 허함수를 순수한 허함수로 대체하자고 제창했다. 허함수는 기본적인 실현을 제공했기 때문에 파생류가 원하는 행위가 이 허함수와 일치하지 않고 허함수를 덮어쓰는 것을 잊어버리면 문제가 발생할 수 있다.그러나 순허함수는 문법 상한선에서 파생류를 정하려면 반드시 그것을 실현해야 하기 때문에, 그렇지 않으면 파생류의 대상을 정의할 수 없다.
또한 순수한 허함수도 기본적으로 실현될 수 있기 때문에 (그러나 파생류는 반드시 다시 정의해야 하며 그렇지 않으면 대상을 정의할 수 없기 때문에) 허함수를 완전히 대체할 수 있다.
 
일반 함수가 대표하는 의미는 불변성 능가와 특이성이기 때문에 파생류에서 다시 정의되어서는 안 된다.
 
디자인 클래스 구성원 함수를 설계할 때 일반적으로 모든 함수를non-virtual(일반 함수)로 성명하지 않기 때문에 특화 작업을 할 여유가 없다.또한 일반적으로 모든 함수를 가상 함수(허함수 또는 순허함수)로 성명하지 마라. 왜냐하면 일반적으로 일부 구성원 함수는 기류로 결정되고 모든 파생류에 의해 공용되기 때문이다.이 설계 법칙은 결코 절대적이지 않으니 실제 상황을 보고 결정해야 한다.
 
마지막으로 요약:
1. 인터페이스 계승과 실현 계승은 다르다.퍼블릭 계승 아래derived class는 항상 베이스 class의 인터페이스를 계승한다.
2.purevirtual 함수는 인터페이스 계승만 구체적으로 지정합니다.
3. impure virtual 함수는 인터페이스 계승과 부족한 계승을 구체적으로 지정한다.
4.non-virutal 함수는 인터페이스 계승을 구체적으로 지정하고 강제적으로 계승을 실현한다.

좋은 웹페이지 즐겨찾기