복사 생성자가 호출되는 세 가지 시점에 대해서 정리해 보겠습니다.
1. 기존에 생성된 객체를 이용해서 새로운 객체를 초기화하는 경우
2. Call - by - value 방식의 함수호출 과정에서 객체를 인자로 전달하는 경우
3. 객체를 반환하되, 참조형으로 반환하지 않는 경우
using namespace std;
class Easy
{
private:
int num;
public:
Easy(int n) : num(n)
{}
Easy(const Easy& copy) : num(copy.num)
{
cout << "Called Easy(const& copy)" << endl;
}
void ShowData()
{
cout << "num: " << num << endl;
}
};
void EasyFunc(Easy ez)
{
ez.ShowData();
}
int main()
{
Easy easy(9);
cout << "함수호출 전" << endl;
EasyFunc(easy);
cout << "함수호출 후" << endl;
Easy easy_ = easy;
}
easy_ 객체를 생성하면서 easy 객체를 대입하면서 복사생성자가 호출이 된다.
다음으로, EasyFunc 함수에 객체를 인자값으로 보내는 과정에서 복사생성자가 호출이 한 번 더 된다. 이때, 복사가 되는 객체는 인자값으로 보내진 easy 객체가 아닌 매개변수 ez 객체가 복사가 되어 easy 멤버 변수 값을 복사받는 것이다.
다음은 세 번째 시점이다.
#include <iostream>
#include <cstring>
#pragma warning(disable:4996)
using namespace std;
class Easy
{
private:
int num;
public:
Easy(int n) : num(n)
{}
Easy(const Easy& copy) : num(copy.num)
{
cout << "Called Easy(const& copy)" << endl;
}
Easy& AddNum(int n)
{
num += n;
return *this;
}
void ShowData()
{
cout << "num: " << num << endl;
}
};
Easy EasyFunc(Easy ez)
{
cout << "return 이전" << endl;
return ez;
}
int main()
{
Easy easy(9);
EasyFunc(easy).AddNum(30).ShowData();
easy.ShowData();
}
위 코드에 실행결과를 입니다.
위 실행 결과에서 다음을 알 수 있습니다.
EasyFunc(easy) 호출시 ez 매개변수가 생성되면서 복사 생성자를 통해 easy 객체에 멤버 변수를 할당을 받는다.
return ez 에서 ez 객체가 return이 되면서 '임시객체'를 생성하여 전달하고 지역적으로 선언된 객체 ez는 소멸된다.
최종적으로 남은 객체는 '임시객체'와 easy객체만 남는다.
또한, 서로다른 num에 출력 값을 통해 임시객체가 easy와 독립적인 주소에 저장이 되었다는 것을 볼 수 있다.
그럼 여기서 '임시객체'가 언제 삭제가 되는지 궁금할 수 있다.
#include <iostream>
#include <cstring>
#pragma warning(disable:4996)
using namespace std;
class Temporary
{
private:
int num;
public:
Temporary(int n):num(n)
{
cout << "Create obj: " << num<<endl;
}
~Temporary()
{
cout << "Destroy obj: " << num << endl;
}
void ShowTempInfo()
{
cout << "My num is " << num << endl;
}
};
int main()
{
Temporary(100);
cout << "After make" << endl;
Temporary(200).ShowTempInfo();
cout << "After make" << endl;
const Temporary& ref = Temporary(300);
cout << "After make" << endl;
}
다음은 실행 결과입니다.
위 결과를 통해 알 수 있는 것은. 임시객체는 생성 후 다은 행으로 넘어가면 바로 소멸되어 버린다는 것입니다. 하지만 참조자에 참조되는 임시객체는 바로 소멸되지 않습니다.
'c++ > 복사 생성자' 카테고리의 다른 글
'깊은 복사'와 '얕은 복사' (2) | 2023.01.03 |
---|---|
[C++] 디폴트 복사 생성자 (0) | 2023.01.03 |