c++의 기본 복사 함수 사용 에 대한 자세 한 설명

에서 복사 함수 가 없 으 면 컴 파일 러 는 자동 으로 기본 복사 함 수 를 만 듭 니 다.다음은 실제 상황 을 살 펴 보 자.
먼저 간단 한 클래스 X 를 보 세 요.이 클래스 는 정의 복사 구조 함 수 를 표시 하지 않 았 습 니 다.c+소스 코드 는 다음 과 같다.

class X {
private:
    int i;
    int j;
};

int main() {
    X x1;// x1
    X x2 = x1;// x1 x2
}

다음은 어 셈 블 리 코드 이다.

_main    PROC

; 7    : int main() {

    push    ebp
    mov    ebp, esp
    sub    esp, 16                    ; x1,x2 16byte

; 8    :     X x1;// x1
; 9    :     X x2 = x1;// x1 x2

    mov    eax, DWORD PTR _x1$[ebp]; x1 eax, x1 i eax
    mov    DWORD PTR _x2$[ebp], eax; eax x2 , eax x2 i
    mov    ecx, DWORD PTR _x1$[ebp+4]; x1 4byte eax, x1 j ecx
    mov    DWORD PTR _x2$[ebp+4], ecx; ecx x2 4byte , ecx x2 j

; 10   : }

    xor    eax, eax
    mov    esp, ebp
    pop    ebp
    ret    0
_main    ENDP

어 셈 블 리 코드 에서 알 수 있 듯 이 함수 가 호출 되 지 않 았 고 모든 복사 할당 값 은 레지스터 와 메모리 주 소 를 통 해 서로 통신 되 었 다.컴 파일 러 가 기본 구조 함 수 를 제공 하 는 것 과 마찬가지 로 이러한 상황 을 컴 파일 러 가 쓸모없는 복사 구조 함 수 를 제공 한 것 으로 볼 수 있다.
그렇다면 컴 파일 러 는 언제 쯤 기본 복사 구조 함 수 를 제공 하고 호출 을 표시 할 수 있 습 니까?
다음은 하나의 상황 입 니 다.클래스 X 에는 가상 구성원 함수 가 포함 되 어 있 습 니 다.
c++소스 코드:

class X {
private:
    int i;
    int j;
public:
    virtual ~X() {}//
};

int main() {
    X x1;// x1
    X x2 = x1;// x1 x2
}

복사 함수 만 토론 하기 때문에 주 함수 main 과 복사 함수 에 있 는 어 셈 블 리 코드 만 봅 니 다.
다음은 주 함수 main 의 어 셈 블 리 코드 입 니 다.

_main    PROC

; 9    : int main() {

    push    ebp
    mov    ebp, esp
    sub    esp, 24                    ; , 12byte i,j8byte vptr 4byte x1 x2 24byte

; 10   :     X x1;// x1

    lea    ecx, DWORD PTR _x1$[ebp]; x1 , ecx, , this
    call    ??0X@@QAE@XZ;

; 11   :     X x2 = x1;// x1 x2

    lea    eax, DWORD PTR _x1$[ebp]; x1 , eax
    push    eax; eax ,
    lea    ecx, DWORD PTR _x2$[ebp]; x2 , ecx, , this
    call    ??0X@@QAE@ABV0@@Z;

; 12   : }

    lea    ecx, DWORD PTR _x2$[ebp]; x2 , ecx , , this
    call    ??1X@@UAE@XZ                ;
    lea    ecx, DWORD PTR _x1$[ebp]; x1 , ecx , , this
                                ;
    call    ??1X@@UAE@XZ                ;
    xor    eax, eax
    mov    esp, ebp
    pop    ebp
    ret    0
_main    ENDP

에서 볼 수 있 습 니 다.컴 파일 러 는 클래스 X 에 기본 복사 구조 함수(쓸모없는 기본 복사 구조 함수 가 아 닌)를 제공 하고 호출 을 표시 합 니 다.
하나의 클래스 가 가상 기 류 를 계승 하거나 자체 가상 함수 구성원 의 기 류 를 계승 하기 때문에 그 자체 에 도 가상 함수 구성원 이 포함 되 어 있 기 때문에 상기 상황 에 속한다.그래서 컴 파 일 러 는 이런 상황 에서 쓸모없는 기본 복사 구조 함 수 를 제공 하고 호출 을 표시 할 수 있다.
다음은 두 번 째 상황 입 니 다.클래스 X 는 클래스 Y 를 계승 하고 클래스 Y 는 정 의 된 복사 구조 함수 가 있 으 며 클래스 는 복사 구조 함 수 를 제공 하지 않 습 니 다.
다음은 c++소스 코드:

class Y {
private:
    int j;
public:
   Y(const Y& y) {}
   Y() {};// Y ,
};
class X : public Y {
private:
    int i;
    int j;
};


int main() {
    X x1;// x1
    X x2 = x1;// x1 x2
}

다음은 mian 함수 어 셈 블 리 코드 입 니 다.

; 16   : int main() {

    push    ebp
    mov    ebp, esp
    sub    esp, 24                    ; x1 x2 24byte

; 17   :     X x1;// x1

    lea    ecx, DWORD PTR _x1$[ebp]; x1 ,
    call    ??0X@@QAE@XZ;// X

; 18   :     X x2 = x1;// x1 x2

    lea    eax, DWORD PTR _x1$[ebp]; x1 , eax
    push    eax; eax , X
    lea    ecx, DWORD PTR _x2$[ebp]; x2 , X
    call    ??0X@@QAE@ABV0@@Z;

; 19   : }

    xor    eax, eax
    mov    esp, ebp
    pop    ebp
    ret    0

다음은 클래스 X 의 복사 구조 함수 의 어 셈 블 리 코드 입 니 다.

??0X@@QAE@ABV0@@Z PROC                    ; X::X, COMDAT
; _this$ = ecx
    push    ebp
    mov    ebp, esp
    push    ecx
    mov    DWORD PTR _this$[ebp], ecx;ecx x2
    mov    eax, DWORD PTR ___that$[ebp]; x1 eax
    push    eax; eax ,
    mov    ecx, DWORD PTR _this$[ebp]; x2 ecx,
    call    ??0Y@@QAE@ABV0@@Z            ;
    mov    ecx, DWORD PTR _this$[ebp]; x2 ecx
    mov    edx, DWORD PTR ___that$[ebp]; x1 edx
    mov    eax, DWORD PTR [edx+4]; x1 4byte eax, x1 i eax, x1 i,
                              ; x2
    mov    DWORD PTR [ecx+4], eax; eax x2 4byte , eax x2 i, x2 i,
                              ;
    mov    ecx, DWORD PTR _this$[ebp]; x2 ecx
    mov    edx, DWORD PTR ___that$[ebp]; x1 edx
    mov    eax, DWORD PTR [edx+8]; x1 8byte eax, x1 j eax
    mov    DWORD PTR [ecx+8], eax; eax x2 8byte , eax x2 j
    mov    eax, DWORD PTR _this$[ebp]; x2 eax, 。
    mov    esp, ebp
    pop    ebp
    ret    4
??0X@@QAE@ABV0@@Z ENDP
어 셈 블 리 코드 에서 볼 수 있 듯 이 컴 파일 러 는 클래스 X 에 기본 적 인 복사 구조 함 수 를 제공 하고 디 스 플레이 호출 을 했 습 니 다.또한 클래스 X 를 호출 하 는 복사 구조 함수 에서 먼저 부모 클래스 의 복사 구조 함 수 를 호출 하고 부모 클래스 의 구성원 변 수 를 복사 한 다음 에 하위 클래스 의 구성원 변 수 를 복사 합 니 다.
다음은 부모 클래스 Y 의 복사 구조 함수 인 코딩 입 니 다.

??0Y@@QAE@ABV0@@Z PROC                    ; Y::Y, COMDAT
; _this$ = ecx

; 5    :    Y(const Y& y) {}

    push    ebp
    mov    ebp, esp
    push    ecx;// this( x2 )
    mov    DWORD PTR _this$[ebp], ecx;ecx x2 ( this),
    mov    eax, DWORD PTR _this$[ebp]; x2 eax, 。
    mov    esp, ebp
    pop    ebp
    ret    4
??0Y@@QAE@ABV0@@Z ENDP                    ; Y::Y
_TEXT    ENDS

어 셈 블 리 에서 볼 수 있 습 니까?부모 클래스 가 스스로 복사 구조 함 수 를 정 의 했 기 때문에 컴 파일 러 는 호출 만 담당 할 뿐 상기 체면 류 X 에서 기본 복사 구조 함수 와 같은 복사 기능 을 제공 하지 않 습 니 다.즉,부모 클래스 구성원 변 수 를 복사 하지 않 습 니 다.c++소스 코드 에서 부모 류 복사 구조 함수 자체 가 빈 함수 이 고 아무것도 하지 않 기 때 문 입 니 다.
만약 하위 클래스 X 부모 클래스 Y 가 복사 구조 함 수 를 제공 하지 않 는 다 면 상황 은 어 떨 까요?
다음은 c++소스 코드:

class Y {
private:
    int j;
};
class X : public Y {
private:
    int i;
    int j;
};


int main() {
    X x1;// x1
    X x2 = x1;// x1 x2
}

다음은 대응 하 는 어 셈 블 리 코드 입 니 다.

_main    PROC

; 12   : int main() {

    push    ebp
    mov    ebp, esp
    sub    esp, 24                    ; x1 x2 24byte

; 13   :     X x1;// x1
; 14   :     X x2 = x1;// x1 x2

    mov    eax, DWORD PTR _x1$[ebp]; x1 , eax, x1 i eax
    mov    DWORD PTR _x2$[ebp], eax; eax x2 , eax x2 i
    mov    ecx, DWORD PTR _x1$[ebp+4]; x1 4byte , ecx, x1 i ecx
    mov    DWORD PTR _x2$[ebp+4], ecx; ecx x2 4byte , ecx x2 i
    mov    edx, DWORD PTR _x1$[ebp+8]; x1 8byte , edx, x1 j edx
    mov    DWORD PTR _x2$[ebp+8], edx; edx x2 8byte , edx x2 j

; 15   : }

    xor    eax, eax
    mov    esp, ebp
    pop    ebp
    ret    0
_main    ENDP

컴 파일 러 는 복사 과정 을 실 행 했 지만 처음에 쓸모없는 기본 복사 구조 함 수 를 제공 합 니 다.부모 클래스 의 구성원 변 수 를 복사 하 든 하위 클래스 의 구성원 변 수 를 복사 하 든 함수 호출 이 없습니다.
다음은 세 번 째 상황 을 보 겠 습 니 다.클래스 X 는 클래스 Y 의 구성원 변 수 를 포함 하고 클래스 Y 의 구성원 변 수 는 복사 구조 함수 가 있 습 니 다.
c++소스 코드 는 다음 과 같 습 니 다.

class Y {
private:
    int j;
public:
    Y(const Y& y) {}
    Y() {}// Y ,
};
class X  {
private:
    int i;
    int j;
    Y y;
};


int main() {
    X x1;// x1
    X x2 = x1;// x1 x2
}

다음은 main 함수 중의 어 셈 블 리 인 코딩 입 니 다.

_main    PROC

; 16   : int main() {

    push    ebp
    mov    ebp, esp
    sub    esp, 24                    ; x1 x2 24byte

; 17   :     X x1;// x1

    lea    ecx, DWORD PTR _x1$[ebp]; x1 ,
    call    ??0X@@QAE@XZ;

; 18   :     X x2 = x1;// x1 x2

    lea    eax, DWORD PTR _x1$[ebp]; x1 , eax
    push    eax; eax ,
    lea    ecx, DWORD PTR _x2$[ebp]; x2 ,
    call    ??0X@@QAE@ABV0@@Z;

; 19   : }

    xor    eax, eax
    mov    esp, ebp
    pop    ebp
    ret    0
_main    ENDP

다음은 컴 파일 러 가 클래스 X 에 제공 하 는 기본 복사 구조 함수 의 어 셈 블 리 인 코딩 입 니 다.

??0X@@QAE@ABV0@@Z PROC                    ; X::X, COMDAT
; _this$ = ecx
    push    ebp
    mov    ebp, esp
    push    ecx; this( x2 )
    mov    DWORD PTR _this$[ebp], ecx;ecx x2 ,
    mov    eax, DWORD PTR _this$[ebp]; x2 eax
    mov    ecx, DWORD PTR ___that$[ebp]; x1 ecx
    mov    edx, DWORD PTR [ecx]; x1 edx, x1 i edx
    mov    DWORD PTR [eax], edx; edx x2 , edx x2 i
    mov    eax, DWORD PTR _this$[ebp]; x2 eax
    mov    ecx, DWORD PTR ___that$[ebp]; x1 ecx
    mov    edx, DWORD PTR [ecx+4]; x1 4byte edx, x1 j edx
    mov    DWORD PTR [eax+4], edx; edx x2 4byte , edx x2 j
    mov    eax, DWORD PTR ___that$[ebp]; x1 eax
    add    eax, 8;// x1 8, x1 y , eax
    push    eax; eax , y
    mov    ecx, DWORD PTR _this$[ebp]; x2 ecx
    add    ecx, 8; x2 8, x2 y , ecx,
    call    ??0Y@@QAE@ABV0@@Z            ; y
    mov    eax, DWORD PTR _this$[ebp]; x2 eax, 。
    mov    esp, ebp
    pop    ebp
    ret    4
??0X@@QAE@ABV0@@Z ENDP
어 셈 블 리 에서 볼 수 있 습 니까?클래스 X 복사 구조 함 수 를 호출 할 때 x1 의 성원 변수 i,j 를 x2 로 복사 합 니 다.그리고 구성원 대상 y 의 복사 구조 함수 복사 y 의 구성원 변 수 를 호출 합 니 다.이것 은 계승 과 달리 계승 에서 항상 부계 의 복사 구조 함 수 를 먼저 호출 한 다음 에 부계 의 복사 함 수 를 진행한다.이 는 이러한 구성원 대상 을 포함 하 는 상황 에 대해 구성원 대상 의 복사 함수 호출 시기 가 그들 이 정의 한 위치 와 관련 이 있다 는 것 을 의미한다.여기 서 클래스 X 의 구성원 대상 y 는 구성원 변수 i,j 이후 에 정의 되 기 때문에 그의 복사 구조 함 수 는 i 를 복사 한 후에 야 j 가 호출 된다.
다음은 클래스 Y 의 복사 구조 함수 어 셈 블 리 코드 입 니 다.

??0Y@@QAE@ABV0@@Z PROC                    ; Y::Y, COMDAT
; _this$ = ecx

; 6    :     Y(const Y& y) {}

    push    ebp
    mov    ebp, esp
    push    ecx; ecx this(x2 y )
    mov    DWORD PTR _this$[ebp], ecx;ecx x2 y ,
    mov    eax, DWORD PTR _this$[ebp]; x2 eax, 。
    mov    esp, ebp
    pop    ebp
    ret    4
??0Y@@QAE@ABV0@@Z ENDP

코드 에서 볼 수 있 습 니 다.클래스 Y 디 스 플레이 가 복사 구조 함 수 를 정 의 했 기 때문에 컴 파일 러 도 디 스 플레이 호출 만 담당 하고 복사 기능 을 제공 하지 않 았 습 니 다.클래스 Y 에서 복사 구조 함 수 는 빈 함수 로 정의 되 기 때문이다.
계승 과 마찬가지 로 멤버 대상 도 구조 함 수 를 복사 하지 않 았 다 면?
다음은 c++소스 코드:

class Y {
private:
    int j;

};
class X  {
private:
    int i;
    int j;
    Y y;
};


int main() {
    X x1;// x1
    X x2 = x1;// x1 x2
}

다음은 대상 의 외환 코드 입 니 다.

_main    PROC

; 14   : int main() {

    push    ebp
    mov    ebp, esp
    sub    esp, 24                    ; 00000018H

; 15   :     X x1;// x1
; 16   :     X x2 = x1;// x1 x2

    mov    eax, DWORD PTR _x1$[ebp]; x1 eax, x1 i eax
    mov    DWORD PTR _x2$[ebp], eax; eax x2 , eax x2 i
    mov    ecx, DWORD PTR _x1$[ebp+4]; x1 4byte ecx, x1 j ecx
    mov    DWORD PTR _x2$[ebp+4], ecx; ecx x2 4byte , ecx x2 j
    mov    edx, DWORD PTR _x1$[ebp+8]; x1 8byte ( x1 y ) edx, x1 y i edx
    mov    DWORD PTR _x2$[ebp+8], edx; edx x2 8byte ( x2 y ) , edx x2 y i

어 셈 블 리 를 통 해 알 수 있 듯 이 컴 파일 러 는 이러한 상황 에서 쓸모없는 기본 복사 구조 함수 만 제공 합 니 다.즉,표시 되 지 않 은 함수 호출 은 레지스터 와 메모리 간 의 통신 으로 복사 과정 을 완성 합 니 다.
위의 분석 을 종합 하면 다음 과 같다.
클래스 에 대해 정의 복사 구조 함 수 를 표시 하지 않 으 면 컴 파일 러 는 항상 쓸모없는 기본 복사 구조 함 수 를 제공 하지 않 습 니 다.
1.이 종 류 는 가상 함수 구성원 함수(가상 클래스 또는 계승 하 는 기본 클래스 에 가상 함수 구성원 포함)를 포함 합 니 다.이때 컴 파일 러 는 이 클래스 에 쓸모없는 기본 복사 구조 함 수 를 제공 합 니 다.
2.이 종 류 는 하나의 기본 클래스 에서 계승 되 고 기본 클래스 는 사용자 정의 복사 함 수 를 포함 합 니 다.이때 컴 파일 러 는 이 클래스 에 쓸모없는 기본 복사 구조 함 수 를 제공 합 니 다.(만약 에 기본 클래스 자체 가 복사 구조 함 수 를 정의 하지 않 았 다 면 컴 파일 러 는 기본 클래스 에 쓸모없는 기본 복사 구조 함 수 를 제공 할 것 이 고 이런 상황 에 속한다.즉,기본 클래스 는 쓸모없는 복사 구조 함수 만 포함 하면 된다.이 쓸모없는 복사 구조 함수 가 사용자 정의 든 컴 파일 러 가 제공 하 든)
3.이 종 류 는 한 구성원 의 대상 을 포함 하고 이 구성원 의 대상 은 자체 적 인 복사 구조 함수 가 있 습 니 다.이때 컴 파일 러 는 이 종류 에 쓸모없는 기본 복사 구조 함 수 를 제공 합 니 다.(만약 에 구성원 대상 자체 가 복사 구조 함 수 를 정의 하지 않 았 다 면 컴 파일 러 는 구성원 대상 에 게 쓸모없는 기본 복사 구조 함 수 를 제공 할 것 이 고 이런 상황 에 속한다.즉,구성원 대상 은 쓸모없는 복사 구조 함수 만 포함 하면 된다.이 쓸모없는 복사 구조 함수 가 아 닐 때 사용자 정의 든 컴 파일 러 가 제공 하 든 간 에.이 중 상황 은 이전 과 유사 하 다.
또한,만약 에 하나의 클래스 가 복사 구조 함 수 를 사용자 정의 한다 면 컴 파일 러 는 호출 만 책임 지고 복사 과정 을 추가 로 제공 하지 않 습 니 다.컴 파일 러 가 제공 하 는 기본 복사 함 수 는 쓸모없는 것 이 든 쓸모없는 것 이 든 모두 비트 복사(즉,얕 은 복사)일 뿐이다.

좋은 웹페이지 즐겨찾기