Transcript 강의5

Chapter 05. 복사 생성자
Chapter 05-1. '복사 생성자'와의 첫 만남
C++ 스타일의 초기화
C 스타일 초기화
C++ 스타일 초기화
이렇듯, 다음 두 문장은 실제로 동일한 문장으로 해석
된다.
SoSimple sim2=sim1;
SoSimple sim2(sim1);
대입연산의 의미처럼 실제 멤버 대 멤버의 복사가
일어난다!
3
SoSimple sim2(sim1);
SoSimple sim2(sim1)의 해석!
SoSimple sim2=sim1 은 묵시적으로 SoSimple sim2(sim1) 으로 해석이 된다.
실행결과
4
자동으로 삽입이 되는 디폴트 복사 생성자
복사 생성자를 정의하지 않으면, 멤버 대 멤버의
복사를 진행하는 디폴트 복사 생성자가 삽입된다.
5
키워드 explicit
이러한 묵시적 형 변환은 복사 생성자를 explicit
으로 선언하면 막을 수 있다.
AAA 생성자를 explicit로 선언하면 AAA
obj=3 과 같은 형태로 객체 생성 불가!
6
Chapter 05-2. ‘깊은 복사’와 ‘얕은 복사’
복사생성자는 기본적으로 "얕은 복사"를 수행한다.
실행결과
객체 소멸 시 문제가 되는 구조!!!
8
얕은 복사!
‘깊은 복사’를 위한 복사 생성자 정의
깊은 복사를 구성하는 복사 생성자!!!
9
Chapter 05-3. 복사 생성자의 호출시점
복사 생성자가 호출되는 시점
메모리 공간의 할당과 초기
화가 동시에 일어나는 상황
case 1
인자 전달 시 선언과 동시에 초기화
case 2 & case 3
반환 시 메모리
공간 할당과 동시에 초기화
11
복사 생성자의 호출 case의 확인1
실행결과
12
복사 생성자의 호출 case의 확인2
인자 전달에 의한
복사 생성자 호출
반환에 의한
복사 생성자 호출
실행결과
13
반환할 때 만들어진 객체의 소멸 시점
참조값이 반환되므로 참
조자로 참조 가능!
실행결과
14
정리
복사생성자는 객체로부터 새 변수가 만들어질 때 호출된다
1. 변수가 선언되면서 다른 객체로 초기화될 때
Person q("Mickey");
Person r(q);
Person p = q;
p = q; (X)
2. 함수의 파라미터 변수가 객체 인자에 의해 초기화될 때
void f(Person person) { person을 활용 };
Person p;
f(p);
3. 함수 실행 결과로 객체가 반환될 때
Person f() { Person q; return q; }
Person p;
Person q = p.f();
15
정리
복사생성자를 작성해야 하는가?





복사생성자가 없는 경우 기본복사생성자가 컴파일러에 의해 자동으로 삽입된
다.
기본복사생성자는 얕은복사를 수행한다.
얕은 복사로 충분한 경우, 프로그래머는 일반적으로 복사생성자를 적어 넣을
필요가 없다.
그러나 클래스가 포인터 멤버변수를 가져 동적메모리할당이 필요한 경우에는
복사생성자를 적어 넣어야 한다.
복사생성자를 적어 넣을 필요가 있는 경우에는 통상 소멸자도 적어 넣을 필요
가 있다.
16
확인문제
C5_1
아래 클래스에는 기본생성자와 소멸자, 기본복사생성자가 없습니다. 컴파일러
에 의해 자동으로 삽입될 기본생성자, 기본소멸자, 기본복사생성자가 어떤 모
양일지 적으시오.
class Point {
private:
int x;
int y;
};
17
확인문제
C5_2
아래 클래스는 포인터 멤버변수를 가져 동적메모리할당이 필요합니다. 이런
경우에는 복사생성자와 소멸자를 적어 넣어 주어야 합니다.
복사생성자와 소멸자를 적절히 삽입하고 이를 시험하는 main 함수를 작성하
시오.
class Person {
private:
char *name;
public:
Person() {
name = new char[20];
}
};
18
실습문제
P5_1
교과서 188쪽 Descructor.cpp 프그램에 복사생성자를 추가하고 복사생
성자의 작동을 시험하도록 main 함수를 적절히 수정하시오. (교과서 문
제 05-1 참고)
P5_2
다음 조건을 만족하는 MyString 클래스와 구동 프로그램을 작성하시오.




19
[클래스 이름]
 MyString
[멤버 변수]
 char *str: 문자열을 가리키는 변수
[멤버 함수]
 void ShowString(void): 저장되어 있는 문자열을 출력하는 함수
[조건]
 다음과 같은 배정문이 가능해야 함
MyString str1(“Hello World!”);
MyString str2 = str1;
실습문제
P5_3
P5_2의 MyString 클래스를 다음과 같이 확장하시오.




20
[클래스 이름]
 MyString
[멤버 변수]
 char *str: 문자열을 가리키는 변수
 int len: 문자열의 길이를 저장하는 변수 (끝의 null은 포함하지 않음)
[멤버 함수]
 void SetString(char *str): 문자열을 저장하는 함수
 char *GetString(void): 저장되어 있는 문자열을 얻어오는 함수
 int GetLength(void): 저장되어 있는 문자열의 길이를 얻어오는 함수
 void ShowString(void): 저장되어 있는 문자열을 출력하는 함수
[조건]
 다음과 같은 배정문이 가능해야 함
MyString str1(“Hello World!”);
MyString str2 = str1;
실습문제
P5_4
P5_3의 MyString 클래스를 다음과 같이 확장하고 적절한 테스트 프로그램을 작
성하시오.

void ToLowerCase(void): 문자열을 소문자로 변환

void ToUpperCase(void): 문자열을 대문자로 변환



21
void AppendString(const char *str1): 문자열의 끝에 str1의 내용을 붙임, str1은
변경되지 말아야 함 (참고: cstring 라이브러리의 strcat 함수를 활용하면 쉽게 구
현할 수 있음)
MyString ConcatString(const char *str1): 문자열의 끝에 str1을 붙여 새로운
MyString 객체를 만들어 반환, 원래의 MyString과 str1은 변경되지 말아야 함
int FindString(const char *str1): 저장된 문자열에서 str1을 찾아서 문자열의 시
작 지점 인덱스를를 반환 (찾지 못했을 경우에는 -1을 반환), (참고: cstring 라이
브러리의 strcmp 함수를 활용하면 쉽게 구현할 수 있음)
Chapter 05가 끝났습니다. 질문 있으
신지요?