복사 생성자는 객체의 복사본을 생성할 때 호출되는 생성자이다.
CMYData a
CmyData b(a)
이처럼 원본 a의 복사본을 만들때 복사 생성자가 불린다.
문법은 클래스이름(const 클래스이름 &rhs) 처럼 사용한다.
#include <iostream>
using namespace std;
class CMYData
{
public:
CMYData() { cout << "기본 생성자" << endl; };
CMYData(const CMYData &rhs)
{
this->m_nData = rhs.m_nData;
cout << "복사 생성자" << endl;
};
int GetData(void) { return m_nData; };
void SetData(int nParam) { m_nData = nParam; };
private:
int m_nData;
};
int main(void)
{
CMYData a;
a.SetData(10);
CMYData b(a);
cout << b.GetData() << endl;
return 0;
}
// 출력값
// 기본 생성자
// 복사 생성자
// 10
이런 식으로 CMYData b(a)와 같은 상황일 때 복사 생성자가 불린다. 여기서 rhs는 원본 즉 a 인스턴스의 참조 변수이다.
이것만 봐서는 도대체 복사 생성자가 왜 중요한지 모르겠다. 하지만 매개변수로 사용되는 복사 생성자를 보면 성능에 대해서 아주 중요한 이야기가 나온다. 결론은 가능하면 무조건 참조형으로 받자! 왜냐? 인스턴스가 하나 더 생성 되니깐
참조형으로 받겠다는 말은 주소로 넘기자 이말이다(call by reference)
매개변수로 사용되는 복사 생성자
#include <iostream>
using namespace std;
class CMYData
{
public:
CMYData(int nParam)
:m_nData(nParam)
{
cout << "기본 생성자" << endl;
};
CMYData(const CMYData &rhs)
:m_nData(rhs.m_nData)
{
cout << "복사 생성자" << endl;
};
int GetData(void) { return m_nData; };
void SetData(int nParam) { m_nData = nParam; };
private:
int m_nData;
};
void TestFunc(CMYData param)
{
cout << "TestFunc" << endl;
param.SetData(20);
}
int main(void)
{
CMYData a(10);
TestFunc(a);
cout << a.GetData() << endl;
return 0;
}
//출력값
//기본 생성자
//복사 생성자
// TestFunc
// 10
다 집어치우고 main함수에서 TestFunc(a)를 호출하면 복사 생성자가 호출된다 왜냐하면 TestFunc의 매개변수는 CMYData param이기 때문이다. 그러니깐 param은 CMYData의 새로운 인스턴스다. 인스턴스를 하나 더 만들었다.
골때린다. 그리고 그 새로운 인스턴스에 20값을 집어 넣어놓고는 인스턴스가 삭제됐다(스택 프레임 종료). 그러니 a는 여전히 10일 수 밖에.. 아무것도 못하고 성능 낭비 메모리 낭비만 하고 사라지는 거지같은 함수 TestFunc다. 이것을 아주 우아하게 바꾸려면 앞에 & 참조만 붙여주면 된다.
바로 void TestFunc(CMYData ¶m)이렇게! 이렇게 해야 call by reference로 주소만 넘긴다! 객체를 생성하지도 않고 성능도 아주 좋다.
'C++' 카테고리의 다른 글
C++ 대입 연산자 (0) | 2020.02.02 |
---|---|
C++ 깊은복사 얕은복사 (0) | 2020.02.02 |
C++ this 포인터 (0) | 2020.02.01 |
C에서 C++ 객체지향의 변환 과정 (0) | 2020.01.28 |
C++ 참조자 형식(reference) (0) | 2020.01.27 |