선언과 동시에 괄호를 통해 초기화 할 경우
선언과 동시에 대입연산자를 사용할 경우
부모클래스의 기본생성자 호출
멤버 클래스의 기본 생성자 호출
기타 선처리
-> 복사 생성자 스코프로 들어감.
복사생성을 하려는 클래스가 상속하고 있을 경우
: 부모클래스의 기본 생성자가 호출된다...
부모의 복사 생성자가 호출되지 않을까? 라고 생각할 수 있지만, 그렇지 않다.
-> 복사 생성자의 스코프가 들어가기 전에 부모클래스의 생성자가 먼저 실행되는 것을 확인할 수 있다.
멤버 클래스가 존재할 경우
멤버 클래스
main 부
-> 멤버 클래스가 존재해서 복사생성자 호출시 멤버 클래스의 기본 생성자가 호출된 후에, 복사생성자가 호출되는 것을 확인할 수 있다.
명시적으로 복사생성자를 만들 경우, 멤버 값 처리를 하지 않았으므로
쓰레기 값이 출력되는 것을 확인할 수 있다.
//그림의 네모칸 잘못쳐짐.ㅎㅎ
암시적 복사 생성자의 경우에는 컴파일러가 알아서 처리한다.
-> 위에서의 동작과는 다르게 부모클래스와 멤버 클래스의 복사 생성자가 호출되는 것을 확인할 수 있따.
부모 클래스 부분
파생클래스 부분,
가 - 1. 명시적으로 호출할때
-> CBase의 복사 생성자에서 변수 처리를 안해서 mValue는 쓰레기값이 나오고, mParent는 기본 생성자에서의 1값이 나오는 것을 확인할 수 있다.
가 - 2. 파생클래스와 부모 클래스의 복사 생성자를 수정하자!
-> 결과 : 가. 에서 부모의 디폴트 클래스가 생성되었는데,
부모의 복사 생성자가 호출되는 것을 확인할 수 있다.
나 : 암시적인 복사 생성자의 경우, 부모의 복사 생성자에서 처리를 해주었기 때문에 문제가 없다.
->
1. 동적할당할 경우 암시적 복사 생성자에서는 얕은 복사 문제가 발생할 수 잇따.
2. 얕은 복사를 해결하기 위해 복사 생성자를 명시적으로 만들어 줬다.
하지만, 부모 클래스가 존재할 경우, 부모 클래스의 복사 생성자에 대한 처리도 해주어야 한다.
: 객체를 복사한다는 것은 두 객체의 메모리 영역만 다르뿐, 값들을 일치한다는 것인데, 여기서 얕은 복사가 발생할 수 있다.
유저는 얕은 복사에 대비해 명시적으로 복사 생성자를 만들어야 하지만,
암시적의 경우에는 자동으로 깊은 복사를 하도록 만들수 없게 설계되어 잇다.
만약에 자동으로 깊은 복사를 하게 한다면, 싱글톤 객체를 가리킬 경우
이런 방식은 문제가 될 소지가 있기 때문이다.
따라서 컴파일러는 암시적 복사 생성자의 경우, 얕은 복사를 제공하므로,
마음에 안들면 유저가 명시적으로 만들어야 한다.
이러한 특성으로 부모와 멤버 클래스의 경우, 암시적일때 복사 생성자가 호출되지만, 명시적일 경우에 부모와 멤버의 복사 생성자도 유저가 직접 호출을 해야한다.
const 나 참조형 멤버 변수가 있을 경우, 복사 대입연산을 진행할 경우, 컴파일 에러가 발생한다.
왜냐하면 const나 참조형의 경우, 초기화할때만 대입연산을 수행하기 때문이다.
따라서 참조타입이거나 const 지정자가 있는 상수 타입 멤버가 잇는 클래스에서는 암시적 복사 대입연산자를 추가할 수 없다.
이런 경우 문제가 발생할 때는 직접 명시적으로 복사 대입연산자를 정의해야 한다.
추가 적으로 암시적인 복사 생성자에서는 문제 되지 않는다.
const를 멤버 변수로 가지고 있을때, 암시적으로 문제가 된다.
명시적으로 복사 대입연산자를 정의하면 문제 없다.
암시적 복사 생성자에서는 컴파일러가 알아서 초기화해준다.