개발/C, C++

[C++] 복사 생성자의 호출시점

huiyu 2018. 12. 29. 13:13

- 복사생성자 : Link
- 복사생성자의 깊은복사 & 얕은복사 : Link

복사 생성자의 호출시점

- 복사 생성자의 호출시점은 크게 세가지로 구분

 1) 기존에 생성된 객체를 이용해 새로운 객체를 초기화 하는 경우

 2) Call-by-value 방식의 함수호출 과정에서 객체를 인자로 전달하는 경우

 3) 객체를 반환하되, 참조형으로 반환하지 않은 경우


1) 기존에 생성된 객체를 이용해 새로운 객체를 초기화 하는 경우

1
2
Person man1("Lee dong woo"29);
Person man2 = man1;
cs

2) Call-by-value 방식의 함수호출 과정에서 객체를 인자로 전달하는 경우

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
#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& copyt)"<<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;
}
cs

[실행결과]
함수 호출 전
Called SoSimple(const SoSimple& copy)
num: 7
함수 호출 후

-> 실행결과를 통해서 함수에 인자를 전달하는 과정에서 복사 생성자가 호출

3) 객체를 반환하되, 참조형을 반환하지 않을 경우

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
#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& copyt)"<<endl;
  }
 
  SoSimple& AddNum(int n)
  {
    num+=n;
    return *this;
  }
 
  void ShowData()
  {
    cout<<"num : "<<num<<endl;
  }
};
 
void SimpleFuncObj(SoSimple ob)
{
  ob.ShowData();
}
 
int main(void)
{
  SoSimple obj(7);
  SimpleFuncObj(obj).AddNum(30).ShowData();
  obj.ShowData();
  return 0;
}
cs

[실행결과]
Called SoSimple(const SoSimple& copy)
return 이전
Called SoSimple(const SoSimple& copy)
num: 37
num: 7

-> 첫번째 복사생성자는 함수의 인자 전달과정에서 호출(return 이전)
 두번째 복사 생성자는 return을 통해 객체를 반환하게 되면서 호출

-> 위그림에서 보듯이 객체를 반환하게 되면, '임시객체'라는 것이 생성되고,
이 객체의 복사생성자가 호출되면서 return문에 명시된 객체가 인자로 전달된다.

즉, 최종적으로 반환되는 객체는 새롭게 생성되는 임시객체이다. 따라서 함수호출이 완료되면, 지역적으로 선언된 객체 ob는 소멸되고 obj 객체와 임시객체만 남는다.


*임시객체의 소멸시점

 - 임시객체는 다음 행으로 넘어가면 바로 소멸
 - 참조자에 참조되는 임시객체는 바로 소멸되지 않는다.

 -> 3+5의 연산에 사용되는 상수 3과 5처럼 임시객체에는 이름이 없기 때문에 다음 행으로 넘어가면 어차피 접근이 불가능해진다.
접근이 불가능하게 된 임시객체는 바로 소멸된다. 반면, 임시객체를 생성하고 참조자로 이를 참조할 경우 다음행에서도 접근이 가능하다. 따라서 바로 소멸 시키지 않는 것이다.

[참고자료]
윤성우의 열혈 C++ 프로그래밍 05-3 복사생성자의 호출 시점

728x90
반응형

'개발 > C, C++' 카테고리의 다른 글

[C++] C++에서의 static  (0) 2018.12.30
[C++] const, friend 키워드  (0) 2018.12.30
[C++] 복사생성자의 깊은복사 & 얕은복사  (0) 2018.12.29
[C++] 복사 생성자(Copy Constructor)  (0) 2018.12.18
[C++] this 포인터  (0) 2018.12.16