C++11 의 default 함수 사용
C++의 클래스 는 네 가지 특수 구성원 함수 가 있 는데 각각 다음 과 같 습 니 다.
기본 구조 함수
분석 함수
복사 구조 함수
복사 할당 연산 자
이러한 종류의 특수 구성원 함 수 는 생 성,초기 화,소각 또는 복사 류 의 대상 을 책임 집 니 다.만약 에 프로그래머 가 특정한 특수 구성원 함 수 를 명시 적 으로 정의 하지 않 고 이 특수 구성원 함 수 를 사용 해 야 할 때 컴 파일 러 는 이러한 종류의 기본 적 인 특수 구성원 함 수 를 암시 적 으로 생 성 합 니 다.예 를 들 면:
명세서
class X{
private:
int a;
};
X x;
목록 1 에서 프로그래머 는 클래스 X 의 기본 구조 함 수 를 정의 하지 않 았 지만 클래스 X 의 대상 x 를 만 들 때 클래스 X 의 기본 구조 함 수 를 사용 해 야 합 니 다.이때 컴 파 일 러 는 클래스 X 에 기본 구조 함 수 를 암시 적 으로 생 성 합 니 다.이 자동 으로 생 성 되 는 기본 구조 함 수 는 인자 가 없고 빈 함수 체,즉 X:X(){}을 포함 합 니 다.자동 으로 생 성 되 는 기본 구조 함 수 는 빈 함수 체 만 있 지만,클래스 X 의 대상 x 를 성공 적 으로 만 드 는 데 사용 할 수 있 으 며,목록 1 도 컴 파일 할 수 있 습 니 다.그러나 프로그래머 가 클래스 X 현식 으로 비 기본 구조 함 수 를 사용자 정의 하 였 으 나 기본 구조 함 수 를 정의 하지 않 았 을 때 목록 2 에 컴 파일 오류 가 발생 할 수 있 습 니 다.
명세서
class X{
public:
X(int i){
a = i;
}
private:
int a;
};
X x; // , X::X()
목록 2 컴 파일 오류 의 원인 은 클래스 X 가 사용자 정의 구조 함수 가 있 기 때문에 컴 파일 러 는 더 이상 암시 적 으로 기본 구조 함 수 를 만 들 지 않 습 니 다.기본 구조 함수 로 클래스 의 대상 을 만 들 려 면 프로그래머 가 기본 구조 함 수 를 직접 정의 해 야 합 니 다.예 를 들 면:명세서
class X{
public:
X(){}; //
X(int i){
a = i;
}
private:
int a;
};
X x; // , X::X()
목록 3 에서 알 수 있 듯 이 컴 파일 러 가 자동 으로 생 성 되 기 를 원 했 던 기본 구조 함 수 는 프로그래머 가 수 동 으로 작성 해 야 합 니 다.즉,프로그래머 의 작업량 이 늘 어 났 습 니 다.또한 수 동 으로 작 성 된 기본 구조 함수 의 코드 실행 효율 은 컴 파일 러 가 자동 으로 생 성 하 는 기본 구조 함수 보다 낮 습 니 다.클래스 의 다른 몇 가지 특수 구성원 함수 도 기본 구조 함수 와 마찬가지 로 사용자 가 정의 한 특수 구성원 함수 가 존재 할 때 컴 파일 러 는 기본 특수 구성원 함 수 를 자동 으로 생 성하 지 않 고 프로그래머 가 수 동 으로 작성 해 야 하 며 프로그래머 의 작업량 을 증가 시 킵 니 다.유사 하 게 수 동 으로 작 성 된 특수 구성원 함수 의 코드 실행 효율 은 컴 파일 러 가 자동 으로 생 성 된 특수 구성원 함수 보다 낮 습 니 다.목록 3 과 같은 두 가지 문 제 를 해결 하기 위해:
프로그래머 의 프로 그래 밍 작업량 감소;
class X{
public:
X()= default;
X(int i){
a = i;
}
private:
int a;
};
X x;
목록 4 에서 컴 파일 러 는 기본 구조 함수 X:X(){}을 자동 으로 생 성 합 니 다.이 함 수 는 사용자 가 정의 한 기본 구조 함수 보다 더 높 은 코드 효율 을 얻 을 수 있 습 니 다.Default 함수 특성 은 클래스 의 특수 구성원 함수 에 만 적용 되 며 이 특수 구성원 함 수 는 기본 매개 변수 가 없습니다.예 를 들 면:
명세서
class X {
public:
int f() = default; // , f() X
X(int) = default; // , X(int, int) X
X(int = 1) = default; // , X(int=1)
};
Default 함 수 는 클래스(inline)에서 정의 할 수도 있 고 클래스 체 외(out-of-line)에서 정의 할 수도 있 습 니 다.예 를 들 면:명세서
class X{
public:
X() = default; //Inline default
X(const X&);
X& operator = (const X&);
~X() = default; //Inline default
};
X::X(const X&) = default; //Out-of-line default
X& X::operator = (const X&) = default; //Out-of-line default
//
C++코드 컴 파일 과정 에서 프로그래머 가 클래스 X 에 대한 분석 함 수 를 정의 하지 않 았 지만 클래스 X 대상 을 없 앨 때 클래스 X 의 분석 함 수 를 호출 해 야 할 때 컴 파일 러 는 자동 으로 암시 적 으로 분석 함 수 를 생 성 합 니 다.이 자동 으로 생 성 되 는 석조 함 수 는 인자 가 없고 빈 함수 체,즉 X::~X(){}을 포함 합 니 다.예 를 들 면:명세서
class X {
private:
int x;
};
class Y: public X {
private:
int y;
};
int main(){
X* x = new Y;
delete x;
}
목록 7 에서 프로그래머 는 기본 클래스 X 와 파생 클래스 Y 에 분석 함 수 를 정의 하지 않 았 습 니 다.주 함수 에서 delete 기본 클래스 포인터 x 를 사용 할 때 기본 클래스 의 분석 함 수 를 호출 해 야 합 니 다.따라서 컴 파일 러 는 클래스 X 에 분석 함 수 를 자동 으로 생 성하 여 x 가 가리 키 는 파생 클래스 대상 의 기본 클래스 하위 대상(즉 int 형 구성원 변수 x)을 성공 적 으로 없 앨 수 있 습 니 다.그러나 이 코드 는 메모리 유출 문제 가 존재 합 니 다.delete 문 구 를 이용 하여 파생 류 대상 을 가리 키 는 지침 x 를 삭제 할 때 시스템 은 파생 류 Y 류 의 분석 함수 가 아 닌 기본 적 인 분석 함수 로 호출 되 기 때문에 컴 파일 러 는 파생 류 의 int 형 구성원 변 수 를 분석 할 수 없습니다.
따라서 일반적인 상황 에서 우 리 는 기본 클래스 의 분석 함 수 를 가상 함수 로 정의 해 야 한다.delete 문 구 를 이용 하여 파생 클래스 대상 을 가리 키 는 기본 지침 을 삭제 할 때 시스템 은 해당 파생 클래스 의 분석 함수(다 형 성 실현)를 호출 하여 메모리 유출 을 피한다.그러나 컴 파일 러 암시 적 자동 으로 생 성 된 분석 함 수 는 모두 비 허 함수 이 므 로 프로그래머 가 수 동 으로 기본 X 로 가상 분석 함 수 를 정의 해 야 합 니 다.예 를 들 어:
명세서
class X {
public:
virtual ~X(){}; //
private:
int x;
};
class Y: public X {
private:
int y;
};
int main(){
X* x = new Y;
delete x;
}
목록 8 에 서 는 프로그래머 가 수 동 으로 기본 X 로 가상 분석 함 수 를 정의 하기 때문에 delete 문 구 를 이용 하여 파생 대상 을 가리 키 는 기본 포인터 x 를 삭제 할 때 시스템 은 해당 파생 류 Y 의 분석 함수(컴 파일 러 암시 적 으로 자동 으로 생 성)와 기본 X 의 분석 함 수 를 호출 하여 파생 류 대상 을 완전 하 게 소각 하여 메모리 유출 을 피 할 수 있 습 니 다.그러나 목록 8 에 서 는 프로그래머 가 기본 클래스 의 허구 함수 정 의 를 수 동 으로 작성 해 야 합 니 다(함수 체 가 비어 있어 도).프로그래머 의 프로 그래 밍 작업량 을 증가 시 켰 습 니 다.특히 수 동 으로 정 의 된 석조 함수 의 코드 실행 효율 은 컴 파일 러 가 자동 으로 생 성 하 는 석조 함수 보다 낮다.
상기 문 제 를 해결 하기 위해 서 우 리 는 기본 클래스 의 가상 분석 함 수 를 default 함수 로 설명 할 수 있 습 니 다.그러면 명시 적 으로 지정 한 컴 파일 러 는 이 함수 에 함수 체 를 자동 으로 생 성 할 수 있 습 니 다.예 를 들 면:
명세서
class X {
public:
virtual ~X()= default; // default
private:
int x;
};
class Y: public X {
private:
int y;
};
int main(){
X* x = new Y;
delete x;
}
C++11 의 default 함수 사용 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 C++11 default 함수 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 바 랍 니 다!