[C++ 문법] '복사 생성자'
'복사 생성자'는 다른 인스턴스의 값을 그대로 복사해서 새로운 인스턴스를 생성할 때 사용됩니다.
'복사 생성자'가 호출되는 경우는 2가지가 있습니다.
1. 명시적으로 객체의 복사본을 생성하는 방식으로 선언
2. 함수 형태로 호출되는 경우
- 클래스가 매개변수로 사용되는 경우
- 클래스가 반환 형식으로 사용되는 경우
1. 명시적으로 객체의 복사본을 생성하는 방식으로 선언
먼저 첫 번째 경우를 코드로 살펴보겠습니다.
void main() {
int a = 10;
int b = a;
}
위의 예제에서 'a'의 값을 'b'에 대입(복사)하면서 생성하였습니다. 이 원리를 클래스에 적용시킨 것이 '복사 생성자'입니다.
class MyData {
private:
int m_nData = 0;
public:
MyData() { /* do somthing */ }
MyData(const MyData& rhs) : m_nData{ rhs.m_nData } { /* do somthing */ }
~MyData() { /* do somthing */ }
int GetData() const { return m_nData; }
void SerData(int nParam) { m_nData = nParam; }
}
void main() {
MyData a; // 디폴트 생성자가 호출됩니다.
a.SetData(10);
MyData b{ a };
cout << b.GetData() << endl;
}
2. 함수 형태로 호출되는 경우
함수 형태로 '복사 생성자'가 호출되는 경우는 클래스가 반환 타입인지 매개변수인지에 따라 나누어집니다. 이 중, 클래스가 반환 형식인 함수는 '이름 없는 임시 객체'를 만들어내니 주의해야합니다.
예제를 살펴보겠습니다.
class CTestData {
private:
int m_nData = 0;
public:
CTestData(int nParam) : m_nData{ nParam } { cout << "CTestData(int)" << endl; }
CTestData(const CTestData& rhs) : m_nData{ rhs.m_nData } { cout << "CTestData(const CTestData&)" << endl; }
int GetData() const { return m_nData; }
void SetData(int nParam) { m_nData = nParam; }
}
// 매개변수가 CTestData 타입입니다. 당연히 해당 스코프에서 사용되기 위해선 변수가 '생성'되어야합니다.
// 호출자가 넘긴 인스턴스의 값을 복사해서 새로운 인스턴스를 생성합니다.
// 이때, '복사 생성자'가 호출됩니다.
void TestFunc(CTestData param) {
cout << "TestFunc()" << endl;
param.SetData(20);
}
void main() {
CTestData a{ 10 };
TestFunc(a); // 함수 내에선 'a' 인스턴스의 값을 '복사'해서 새로운 인스턴스를 만듭니다.
cout << "a: " << a.GetData() << endl;
}
여기서 문제는 TestFunc() 함수에서 매개변수로 넘어온 CTestData 인스턴스를 '복사'해서 새로 '생성'한다는겁니다. 쓸 데 없이 인스턴스 하나를 '생성'하는데 드는 비용과 '복사'하는데 드는 비용이 발생합니다. 사실 함수를 이렇게 사용할거라면 굳이 C++를 사용할 이유가 없습니다. 간단히 &(참조자)로 받으면 이 문제는 싹 해결됩니다.
(참고로, *(포인터)는 댕글링 포인터, 의존 관계 분석 불가로 인한 코드 최적화 실패 등의 단점이 있습니다. 이러한 *(포인터)의 단점을 보완해서 나온게 &(참조자)입니다.)
'Programming > C C++' 카테고리의 다른 글
[C++ 문법] '이동 생성자' (0) | 2019.05.22 |
---|---|
[C++ 문법] '변환 생성자' (0) | 2019.05.21 |
[C++ 문법] '정적(static) 멤버' (0) | 2019.05.20 |
[C++ 문법] 'mutable' 예약어와 'const_cast<>' 형변환 연산자 (0) | 2019.05.20 |
[C] 'inline 함수' (0) | 2019.05.19 |
댓글
이 글 공유하기
다른 글
-
[C++ 문법] '이동 생성자'
[C++ 문법] '이동 생성자'
2019.05.22 -
[C++ 문법] '변환 생성자'
[C++ 문법] '변환 생성자'
2019.05.21 -
[C++ 문법] '정적(static) 멤버'
[C++ 문법] '정적(static) 멤버'
2019.05.20 -
[C++ 문법] 'mutable' 예약어와 'const_cast<>' 형변환 연산자
[C++ 문법] 'mutable' 예약어와 'const_cast<>' 형변환 연산자
2019.05.20