일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 화장품
- 투자
- 독서
- 자바스크립트
- 지혜를가진흑곰
- algorithmStudy
- 돈
- C
- 프로그래밍언어
- 서평
- 다독
- Java
- 성분
- 독후감
- 자바
- 채권
- 알고리즘트레이닝
- 재테크
- 주식
- JavaScript
- C++
- 알고리즘공부
- algorithmtraining
- 프로그래머스 알고리즘 공부
- 백준알고리즘
- 알고리즘 공부
- algorithmTest
- 경제
- 책알남
- 책을알려주는남자
- Today
- Total
탁월함은 어떻게 나오는가?
[C++] 복사생성자 '얕은 복사' '깊은 복사' 본문
복사 생성자(copy constructor)란 같은 클래스의 객체를 복사하여 객체를 만드는 생성자입니다. 만일 복사 생성자를 명시적으로 선언하지 않으면 컴파일러는 원본 객체의 멤버들을 그대로 복사하여 객체를 정의하는 복사 생성자를 자동으로 만듭니다. 복사 생성자는 파라미터를 자기 클래스 타입의 참조 변수 하나만 가지며, 때문에 하나의 복사 생성자만 존재할 수 있습니다.
복사에는 두 가지 복사가 존재하는데, 1.얕은 복사(swallow copy)와 2.깊은 복사(deep copy)가 있습니다. 두 가지 복사를 나누는 핵심은 메모리의 할당에 있다. 멤버 변수에는 다양한 변수들이 존재하며, primitive type이 있을 수도 있고, 다른 클래스의 객체가 존재 할 수도 있고, 포인터가 존재 할 수도 있습니다. 이때 멤버 중 하나가 동적 할당을 받는 변수라고 한다면, 이럴경우 1.얕은 복사의 경우 동적 할당을 받은 변수의 주소값을 공유합니다. 2.깊은 복사의 경우에는 새로이 동적 할당은 받고, 원본의 데이터까지 복사를 합니다. 이것이 얕은복사와 깊은복사의 차이입니다.
1. 얕은 복사
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
#include <iostream>
using namespace std;
class Person
{
public:
int age;
char* name;
public:
Person(int _age, const char* _name)
{
age = _age;
name = new char[strlen(_name) + 1];
strcpy(name, _name);
}
Person(const Person& fv)
{
age = fv.age;
name = fv.name;
}
~Person()
{
cout << "소멸!" << endl;
delete name;
}
void printPs()
{
cout << "이름 : " << name << endl;
cout << "나이 : " << age << endl;
}
};
void main()
{
Person A(30, "Shot");
Person B = A;
A.age = 32;
strcpy(A.name, "Long");
A.printPs();
B.printPs();
}
|
cs |
코드에서 name은 주소값을 참조하기 때문에 복사를 하였더라도 같은 주소를 참조하게 됩니다. 그렇기 때문에 A의 name값이 바뀌면 B의 name의 값까지 변경이 됩니다.
또한, 소멸자 또한 호출될 때 name은 같은 메모리를 참조하기 때문에 소멸된(delete) 메모리를 다시 소멸시킬수 없어서 에러가 발생하게 됩니다.
2. 깊은 복사
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#include <iostream>
using namespace std;
class Person
{
public:
int age;
char* name;
public:
Person(int _age, const char* _name)
{
age = _age;
name = new char[strlen(_name) + 1];
strcpy(name, _name);
}
Person(const Person& fv)
{
age = fv.age;
name = new char[strlen(fv.name) + 1];
strcpy(name, fv.name);
}
~Person()
{
cout << "소멸!" << endl;
delete name;
}
void printPs()
{
cout << "이름 : " << name << endl;
cout << "나이 : " << age << endl;
}
};
void main()
{
Person A(30, "Shot");
Person B = A;
A.age = 32;
strcpy(A.name, "Long");
A.printPs();
B.printPs();
}
|
cs |
깊은 복사로만든 값에서는 오류가 발생하지 않습니다. 이유는 새로운 메모리를 할당했기 때문이죠. 원본과 복사본의 참조 공간이 다르기 때문에 소멸자도 각각 실행됨으로써 오류가 발생하지 않게됩니다.
'[Snow-ball]프로그래밍(컴퓨터) > C, C++' 카테고리의 다른 글
특수문자 출력하기 (0) | 2020.11.25 |
---|---|
[C++] 복사생성자 '얕은 복사' '깊은 복사' (0) | 2020.11.08 |
[C++] Error C4996 : 'strcpy', 'strcat' 오류에 대해서 (0) | 2020.11.08 |
[C++] 반복문 (0) | 2020.10.16 |
[C++] 조건문 (0) | 2020.10.16 |