5. 복사 생성자(윤성우 열혈강의 C++ 예제코드)
출처: 윤성우 열혈강의 C++ 예제코드
5.1. ‘복사 생성자’와의 첫 만남
- 복사 생성자 직접 선언하기
#include <iostream>
using namespace std;
class SoSimple
{
private:
int num1;
int num2;
public:
SoSimple(int n1, int n2)
: num1(n1), num2(n2)
{
// empty
}
SoSimple(const SoSimple ©)
: num1(copy.num1), num2(copy.num2)
{
cout<<"Called SoSimple(SoSimple ©)"<<endl;
}
void ShowSimpleData()
{
cout<<num1<<endl;
cout<<num2<<endl;
}
};
int main(void)
{
SoSimple sim1(15, 30);
cout<<"생성 및 초기화 직전"<<endl;
SoSimple sim2=sim1;
cout<<"생성 및 초기화 직후"<<endl;
sim2.ShowSimpleData();
return 0;
}
- explicit 키워드로 대입연산자에서의 복사생성자 호출막기
explicit SoSimple(const SoSimple ©)
: num1(copy.num1), num2(copy.num2)
{
cout<<"Called SoSimple(SoSimple ©)"<<endl;
}
5.2. ‘깊은 복사’와 ‘얕은 복사’
- shallow copy
#include <iostream>
#include <cstring>
using namespace std;
class Person
{
char * name;
int age;
public:
Person(char * myname, int myage)
{
int len=strlen(myname)+1;
name=new char[len];
strcpy(name, myname);
age=myage;
}
void ShowPersonInfo() const
{
cout<<"이름: "<<name<<endl;
cout<<"나이: "<<age<<endl;
}
~Person()
{
delete []name;
cout<<"called destructor!"<<endl;
}
};
int main(void)
{
Person man1("Lee dong woo", 29);
Person man2=man1;
man1.ShowPersonInfo();
man2.ShowPersonInfo();
return 0;
}
이름: Lee dong woo
나이: 29
이름: Lee dong woo
나이: 29
called destructor!
- deep copy
#include <iostream>
#include <cstring>
using namespace std;
class Person
{
char * name;
int age;
public:
Person(const Person ©)
: age(copy.age)
{
name = new char[strlen(copy.name) + 1];
strcpy(name, copy.name);
}
Person(char * myname, int myage)
{
int len = strlen(myname) + 1;
name = new char[len];
strcpy(name, myname);
age = myage;
}
void ShowPersonInfo() const
{
cout << "이름: " << name << endl;
cout << "나이: " << age << endl;
}
~Person()
{
delete[]name;
cout << "called destructor!" << endl;
}
};
int main(void)
{
Person man1("Lee dong woo", 29);
Person man2 = man1;
man1.ShowPersonInfo();
man2.ShowPersonInfo();
return 0;
}
이름: Lee dong woo
나이: 29
이름: Lee dong woo
나이: 29
called destructor!
called destructor!
5.3. 복사 생성자의 호출시점
- 기존에 생성된 객체를 이용해서 새로운 객체를 초기화
Person man1("Lee dong woo", 29);
Person main2 = main1;
- 매개변수 전달시점의 호출
#include <iostream>
using namespace std;
class SoSimple
{
private:
int num;
public:
SoSimple(int n) : num(n)
{ }
SoSimple(const SoSimple& copy) : num(copy.num)
{
cout<<"Called SoSimple(const SoSimple& copy)"<<endl;
}
void ShowData()
{
cout<<"num: "<<num<<endl;
}
};
void SimpleFuncObj(SoSimple ob)
{
ob.ShowData();
}
int main(void)
{
SoSimple obj(7);
cout<<"함수호출 전"<<endl;
SimpleFuncObj(obj);
cout<<"함수호출 후"<<endl;
return 0;
}
- 결과값 반환시의 호출
#include <iostream>
using namespace std;
class SoSimple
{
private:
int num;
public:
SoSimple(int n) : num(n)
{ }
SoSimple(const SoSimple& copy) : num(copy.num)
{
cout<<"Called SoSimple(const SoSimple& copy)"<<endl;
}
SoSimple& AddNum(int n)
{
num+=n;
return *this;
}
void ShowData()
{
cout<<"num: "<<num<<endl;
}
};
SoSimple SimpleFuncObj(SoSimple ob)
{
cout<<"return 이전"<<endl;
return ob;
}
int main(void)
{
SoSimple obj(7);
SimpleFuncObj(obj).AddNum(30).ShowData();
obj.ShowData();
return 0;
}
- 임시객체의 소멸시점 확인
#include <iostream>
using namespace std;
class SoSimple
{
private:
int num;
public:
SoSimple(int n) : num(n)
{ }
SoSimple(const SoSimple& copy) : num(copy.num)
{
cout<<"Called SoSimple(const SoSimple& copy)"<<endl;
}
SoSimple& AddNum(int n)
{
num+=n;
return *this;
}
void ShowData()
{
cout<<"num: "<<num<<endl;
}
};
SoSimple SimpleFuncObj(SoSimple ob)
{
cout<<"return 이전"<<endl;
return ob;
}
int main(void)
{
SoSimple obj(7);
SimpleFuncObj(obj).AddNum(30).ShowData();
obj.ShowData();
return 0;
}
New Object: 0039F7EC
New Copy obj: 0039F6D0
Parm ADR: 0039F6D0
New Copy obj: 0039F708
Destroy obj: 0039F6D0
Destroy obj: 0039F708
New Copy obj: 0039F6D0
Parm ADR: 0039F6D0
New Copy obj: 0039F7E0
Destroy obj: 0039F6D0
Return Obj 0039F7E0
Destroy obj: 0039F7E0
Destroy obj: 0039F7EC