Game Develop

객체복사 할 때는 빠짐없이 복사하자. 본문

C++/Effective C++

객체복사 할 때는 빠짐없이 복사하자.

MaxLevel 2025. 11. 14. 22:53

객체를 복사해야 하는 경우(복사생성이나 대입연산), 말 그대로 모든 부분을 빠짐없이 복사해야 한다.

 

상속관계인 두 클래스가 있을 때, 자식클래스에서 복사생성을 정의할 경우 부모클래스의 복사생성은 호출되지 않는다.

물론 따로 정의 안하면, 기본컴파일러가 부모것까지 얕은복사를 해준다.

 

 

자 그러면 여기서 자식클래스에서 복사생성자랑 대입연산자를 정의해보자.

 

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <string>
 
using namespace std;
 
 
 
 
class Parent
{
 
public:
    Parent() {};
 
    /*Parent(const Parent& rhs) : name(rhs.name)
    {
        cout << "Parent CopyConstructor" << endl;
    }
 
    Parent& operator=(const Parent& rhs)
    {
        cout << "Parent AssignmentOperator" << endl;
    }*/
 
 
    string name = "default";
};
 
 
 
class Child : public Parent
{
 
public:
    Child() {};
 
    Child(const Child& rhs) : value(rhs.value)
    {
        cout << "Child CopyConstructor" << endl;
    }
 
    Child& operator=(const Child& rhs)
    {
        cout << "Child AssignmentOperator" << endl;
 
        this->value = rhs.value;
 
        return *this;
    }
 
    int value = 0;
};
 
 
 
int main()
{
    Child c1;
    c1.name = "c1Name";
    c1.value = 1;
 
    Child c2(c1); // 복사생성
    Child c3;
    c3 = c1;
 
    cout << endl << endl;
 
    cout << c2.name << ' ' << c2.value << endl;
    cout << c3.name << ' ' << c3.value << endl;
}
cs

 

보면 자식클래스에만 복사생성자랑 대입연산자가 정의되어 있다.

이상태로 출력을 하면

 

 

 

이런 결과가 나온다.

자식클래스에서만 복사생성자와 대입연산자를 정의했기 때문에 부모클래스의 변수값은 default로 설정한 그대로이다.

위의 코드에는 부모클래스의 복사생성자와 대입연산자가 주석처리 되어있긴 한데, 주석처리가 되어있든 아니든 자식클래스것만 호출한다.

 

그렇기 때문에 자식클래스에서 호출할 때 부모것의 객체도 복사해주는 기능이 수행되어져야 한다.

복사생성할 때는 자식클래스것만 Default Member Initialize하지 말고, 아래처럼 부모를 같이 호출해 주면 된다.

 

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <iostream>
#include <string>
 
using namespace std;
 
 
 
 
class Parent
{
 
public:
    Parent() {};
 
    Parent(const Parent& rhs) : name(rhs.name)
    {
        cout << "Parent CopyConstructor" << endl;
    }
 
    Parent& operator=(const Parent& rhs)
    {
        this->name = rhs.name;
        cout << "Parent AssignmentOperator" << endl;
 
        return *this;
    }
 
 
    string name = "default";
};
 
 
 
class Child : public Parent
{
 
public:
    Child() {};
 
    Child(const Child& rhs) : Parent(rhs), value(rhs.value)
    {
        cout << "Child CopyConstructor" << endl;
    }
 
    Child& operator=(const Child& rhs)
    {
        cout << "Child AssignmentOperator" << endl;
 
        Parent::operator=(rhs);
        this->value = rhs.value;
 
        return *this;
    }
 
    int value = 0;
};
 
 
 
int main()
{
    Child c1;
    c1.name = "c1Name";
    c1.value = 1;
 
    Child c2(c1); // 복사생성
    Child c3;
    c3 = c1; // 대입연산
 
    cout << endl << endl;
 
    cout << c2.name << ' ' << c2.value << endl;
    cout << c3.name << ' ' << c3.value << endl;
}
cs

 

 

 

 

 

보면 깔끔하게 객체복사가 된 것을 확인할 수 있다.