- C++ 스타일 초기화
int num = 20;
int &ref = num;
or
int num(20);
int &ref(num);
-> C++에서는 위의 두가지 초기화 방식을 동시에 지원한다.
*객체에서는?
-> 객체에서도 변수의 초기화와 같이 대입, 괄호 두가지 초기화 방식을 모두 지원한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class SoSimple { private: int num1; int num2; public: SoSimple(int n1, int n2) : num1(n1), num2(n2) {} void ShowSimpleData() { cout<<num1<<endl; cout<<num2<<endl; } }; int main(void) { SoSimple sim1(15, 20); SoSimple sim2 = sim1; sim2.ShowSimpleData(); return 0; } | cs |
출력 결과 15와 20이 출력된다.
* SoSimple sim2 = sim1
-> sim2객체가 생성된 다음, sim2객체로 sim1의 멤버변수의 복사가 일어난다.
SoSimple sim2 = sim1은 실은 SoSimple sim2(sim1)의 형태로 묵시적 변환이 되어서(자동으로 변환이 되어서) 객체가 생성되는 것이다.
SoSimple sim2(sim1);<-이 문장에 담겨있는 내용을 정리하면,
1) SoSimple형 객체를 생성
2) 생성한 객체의 이름은 sim2로 지정
3) sim1을 인자로 받을 수 있는 생성자의 호출을 통해 객체생성을 완료
3)을 호출하기 위한 SoSimple을 인자로 받는 생성자는 아래의 형태이다.
1 2 3 4 | SoSimple(const SoSimple ©) : num1(copy.num1), num2(copy.num2) { .... } | cs |
** 이러한 생성자를 가리켜 '복사 생성자(Copy constructor)'라 부른다.
키워드 const를 삽입해서 복사에 사용되는 원본의 변경을 막는다.
**위의 예제에선 선언하지 않은 함수인데?
-> 복사생성자를 정의하지 않으면, 멤버 대 멤버의 복사를 진행하는 '디폴트 복사 생성자'가 자동으로 삽입된다.
- explicit 키워드
위 예제에서
SoSimple sim2 = sim1;
의 코드는
SoSimple sim2(sim1)
의 형태로 묵시적 변환이 일어나 복사 생성자가 호출된다고 하였다.
이는 결국, 복사 생성자가 묵시적으로 호출된 것으로 볼 수 있다.
이러한 묵시적 호출을 막기 위해서 사용 하는 키워드가 explicit 키워드이다.
1 2 3 4 | explicit SoSimple(const SoSimple ©) : num1(copy.num1), num2(copy.num2) { .... } | cs |
-> 위와 같이 선언하면 대입연산자를 이용한 객체의 생성 및 초기화가 불가능하다.
*이러한 묵시적 변환은 복사생성자에서만 일어나는게 아니다.
1 2 3 4 5 6 7 8 9 | class AAA { private: int num; public: AAA(int n) : num(n) { } ..... }; | cs |
위와같은 클래스가 있을 경우, 아래와 같이 객체 생성이 가능하다.
AAA obj = 3; // AAA obj(3);으로 변환
그러나 생성자에 explicit가 선언되었다면, 위의 형태로 초기화가 불가능하다.
[참고자료]
윤성우 열혈 C++ 프로그래밍 05-1 '복사 생성자'와의 첫만남
'Software Development > C, C++' 카테고리의 다른 글
[C++] 복사 생성자의 호출시점 (1) | 2018.12.29 |
---|---|
[C++] 복사생성자의 깊은복사 & 얕은복사 (0) | 2018.12.29 |
[C++] this 포인터 (0) | 2018.12.16 |
[C++] 생성자(Constructor)와 소멸자(Destructor) (0) | 2018.12.16 |
[C++] 정보은닉(Information Hiding) (0) | 2018.12.15 |