Effective C + + Item 7 은 다 중 기본 클래스 성명 virtual 분석 함수 입 니 다.
경험 1: 다 중 성질 을 가 진 기본 클래스 는 virtual 분석 함 수 를 설명 해 야 합 니 다.만약 class 가 어떤 virtual 함 수 를 가지 고 있다 면, 그것 은 virtual 분석 함 수 를 가지 고 있어 야 한다
예제: 다 중 성질 을 가 진 기본 클래스 에 가상 분석 함 수 를 설명 하지 않 습 니 다.
출력:
TimeKeeper destructor
해석:
derived class 대상 이 base class 지침 을 통 해 삭제 되 었 을 때, 이 base class 는 non - virtual 분석 함 수 를 가지 고 있 으 며, 그 결 과 는 정의 되 지 않 았 습 니 다. 실제 실행 할 때 대상 의 derived 성분 이 소각 되 지 않 아 자원 이 누 출 되 는 경우 가 많 습 니 다.
교정: 다 중 성질 을 가 진 기본 클래스 에 가상 분석 함 수 를 설명 합 니 다.
#include <iostream>
#include <string>
using namespace std;
class TimeKeeper
{
public:
~TimeKeeper(){cout << "TimeKeeper destructor" << endl;}
};
class AtomicClock: public TimeKeeper{
~AtomicClock(){cout << "AtomicClock destructor << endl";}
};
class WaterClock: public TimeKeeper{
~WaterClock(){cout << "WaterClock destructor << endl";}
};
TimeKeeper* getTimeKeeper(string type){
if(type == "AtomicClock") return new AtomicClock();
else return new WaterClock();
}
int main(){
TimeKeeper *tk = getTimeKeeper("AtomicClock");
delete tk;
system("pause");
}
출력:
AtomicClock destructor
TimeKeeper destructor
경험 2: classes 의 디자인 목적 이 base classes 로 사용 되 지 않 거나 다 형 성 을 갖 추기 위해 서가 아니라면 가상 분석 함 수 를 설명 하지 말 아야 합 니 다.
예시:
#include <iostream>
#include <string>
using namespace std;
class TimeKeeper
{
public:
virtual ~TimeKeeper(){cout << "TimeKeeper destructor" << endl;} // virtual
};
class AtomicClock: public TimeKeeper{
~AtomicClock(){cout << "AtomicClock destructor" << endl;}
};
class WaterClock: public TimeKeeper{
~WaterClock(){cout << "WaterClock destructor << endl";}
};
TimeKeeper* getTimeKeeper(string type){
if(type == "AtomicClock") return new AtomicClock();
else return new WaterClock();
}
int main(){
TimeKeeper *tk = getTimeKeeper("AtomicClock");
delete tk;
system("pause");
}
출력:
8
12
해석:
p1 의 size 는 8: 두 int 유형 은 각각 4 개의 바이트 이기 때문에 모두 8 개의 바이트 p2 의 size 는 12: 두 int 유형 은 각각 4 개의 바이트, 총 8 개의 바이트 이다.가상 함수 가 있 기 때문에 대상 은 가상 포인터 vptr (virtual table pointer) 를 가 져 가 야 합 니 다. vptr 는 함수 포인터 로 구 성 된 배열 을 가리 키 며 vtble (virtual table) 이 라 고 부 릅 니 다. 실행 기간 에 어떤 virtual 함수 가 호출 될 지 결정 합 니 다.구체 적 으로 허 표 지침 에 관 한 문 제 는 진 호의 블 로그 (http://blog.csdn.net/haoel/article/details/1948051 )。
출력 결 과 를 통 해 알 수 있 듯 이 모든 classes 의 석조 함 수 를 virtual 로 무 단 설명 하면 class 대상 의 저장 공간 이 증가 합 니 다. 따라서 class 에 최소한 하나의 virtual 함수 가 포함 되 어 있 을 때 만 석조 함 수 를 virtual 로 설명 합 니 다.
경험 치 3: 표준 용기 나 "non - trivial 분석 함수" 를 포함 하 는 class 를 계승 하려 고 하지 마 십시오. 예 를 들 어 string, vector, list, set 등 입 니 다.
예시:
#include <iostream>
#include <string>
using namespace std;
class Point1{
public:
~Point1(){};
private:
int x, y;
};
class Point2{
public:
virtual ~Point2(){};
private:
int x, y;
};
int main(){
Point1 p1;
Point2 p2;
cout << sizeof(p1) << endl
<< sizeof(p2) << endl;
system("pause");
}
출력:
(비어 있다)
해석:
표준 string 은 어떠한 virtual 함수 도 포함 하지 않 습 니 다. delete 는 SpecialString 형식의 지침 을 가리 키 며 string 류 의 분석 함수 만 호출 합 니 다. SpecialString 의 분석 함 수 는 호출 되 지 않 습 니 다. 현실 적 으로 * ps 의 SpecialString 자원 이 누 출 됩 니 다. 이것 은 경험 1 과 마찬가지 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.