C++ 아이콘 제작자: Darius Dan - Flaticon
class A {
int data_;
public:
A(int data) : data_(data) { std::cout << "일반 생성자 호출!" << std::endl; }
A(const A& a) : data_(a.data_) {
std::cout << "복사 생성자 호출!" << std::endl;
}
};
A c(A(2)); ==> 일반 생성자가 호출됨
위 예시에서 내가 생각한 것은 A(2)에서 일반 생성자 호출후 임시 객체에 c가 복사되며 복사생성자가 호출될 것을 예상했지만 아니네?
사실 굳이 임시 객체 1번 만들고 여기에 복사를 할 필요가 없다.
==> 그냥 A(2)를 c로 만들꺼면 처음부터 c자체를 A(2)로 만들어진 객체로 해버리자그래서 컴파일러는 굳이 복사 생성을 하지 않고 만들어진 A(2) 자체를 c로 만든다
이것이 복사 생략이다.
int&& r_b = 3; 우측값
int&& rr_b = a; // 불가능 , 좌측값
- 이동 생성자를 호출하면 사라지는 값인 우측값을 계속 갖고 있는 것 처럼 보이는데
우선 원본 객체에서 데이터를 가져와서 새로 생성될 객체에 할당하고 nullptr로 원본 객체는 사라지지 않고 접근을 못하게 한다.nullptr은 C++ 11 에 새로 추가된 키워드로, 기존의 NULL 대체
포인터 주소값 0을 명확하게 표현
- 먼저 그냥 복사 생성자로 vector의 할당한 메모리가 부족할 때 새로 공간을 할당하여 원소들 모두 복사를 한다.
이 과정에서 예외가 일어난다면 새로 할당한 메모리를 소멸시킨후 예외를 전달하게 될 것이다.
- 그런데 이동 생성자는 그럴 수 없다.
복사 생성은 복사를 하고 새로운 공간에 할당해서 그 공간을 소멸시켜도 기존 원소는 존재하지만
이동 생성의 경우 기존 메모리에서 원소들이 모두 이동되어 사라지기에
섯불리 새 메모리를 해제를 하면 원소 자체가 사라진다.
- 따라서 이동 생성자에서 예외 발생시 처리를 못한다.
==> 이동 생성자는 noexcept가 아닌 이상 사용이 불가하다.
개인 공부 기록용 블로그입니다.
틀린 부분 있으다면 지적해주시면 감사하겠습니다!!