[CS] 암시적 멤버 메서드 6가지 (기본생성자, 기본소멸자, 복사생성자, 이동생성자, 복사대입연산자, 이동대입연산자)
1. 기본생성자
2. 기본소멸자
3. 복사생성자
4. 이동생성자
5. 복사대입연산자
6. 이동대입연산자
🔷 기본 생성자 (=디폴트 생성자, Default Constructor)
원형
Book::Book() { }
- 기본 생성자는 객체가 생성될 때 사용자가 초깃값을 명시하지 않으면, 컴파일러가 자동으로 제공하는 생성자이다.
즉, 클래스에 생성자가 단 하나도 정의되지 않았을 때만, 컴파일러에 의해 자동으로 제공된다.
만약, 사용자가 생성자를 단 하나라도 정의했다면 위와 같은 객체의 선언은 오류를 발생시킨다. - 기본 생성자는 사용자로부터 인수를 전달받지 않으므로, 매개변수를 가지지 않는다.
🔷 기본 소멸자 (Default Destructor)
원형
~Book() { }
- 객체의 수명이 끝나면 생성자의 반대 역할을 수행하는 소멸자가 컴파일러에 의해 자동으로 호출되며, 사용이 끝난 객체를 정리해준다.
- 소멸자는 인수를 가지지 않고, 반환값이 없지만 void형으로 선언하지 않는다.
- 생성자는 여러 개를 가질 수 있지만, 소멸자는 단 하나만 가질 수 있다.
- 메모리 영역 별 소멸자 호출 시기

🔷 복사 생성자
원형
Book(const Book& b);
- 복사생성자는 한 객체의 내용을 다른 객체로 복사하여 생성된 생성자를 의미한다.
- 자신과 같은 클래스 타입의 다른 객체에 대한 참조(&, reference)를 인수로 전달받아, 그 참조를 가지고 자신을 초기화하는 방법이다.
- 복사 생성자를 이용한 대입은 깊은 복사(deep copy)를 통한 값의 복사이기 때문에 새롭게 생성되는 객체가 원본 객체와 같으면서도, 완전한 독립성을 가지게 해준다.
- 그러나, 복사생성자가 정의되어 있지 않다면, 컴파일러가 자동으로 디폴트 복사생성자를 생성한다.
디폴트 복사생성자는 깊은 복사가 아닌 얕은 복사를 수행하기 때문에 객체 내에 동적할당된 변수가 있다면 문제가 발생할 수 있다.
얕은복사의 문제점?
얕은 복사를 한 객체와 대상 중 어느 하나를 메모리 해제하면 메모리 할당 에러가 발생하게 된다. 얕은 복사는 여러개의 포인터가 하나의 주소를 가리키고 있는데, 객체를 각각 해제할 때 하나의 포인터를 두번 해제하게 되기 때문이다. 즉, 얕은 복사를 수행한 객체 A와 객체 B의 동일한 변수 p가 두번이나 해제되어 오류를 일으키는 것이다.
- 복사생성자가 사용되는 경우
- 객체가 함수에 인수로 전달될 때
- 함수가 객체를 반환값으로 반환할 때
- 새로운 객체를 같은 클래스 타입의 기존 객체와 똑같이 초기화할 때
🔷 이동 생성자
원형
Book::Book(Book&& other); // 복사생성자와 달리 const가 없다!
- 이동생성자는 얕은 복사를 통해 객체를 가져오고, 가져온 객체의 모든 소유권을 이동 대상으로 이전(move)하는 방식으로 객체를 생성한다.
- 이동생성자는 복사 생성자와 달리, 얕은 복사로 메모리를 재할당 하지 않기 때문에 복사 생성자보다 빠르다.
- 소유권을 이동 대상으로 이동시킨 후에는, 얕은 복사가 된 포인터의 소유권을 반드시 NULL로 박탈시켜 주어야 한다.
이동 후 소유권 박탈 예시 코드

- 이동생성자의 호출 상황
1. 임시 객체를 전달할 때
2. std::move() 함수를 사용하여 인자를 RValue 참조자로 변환하여 전달할 때
(move 함수는 lvalue를 rvalue로 변환하여 반환하는 함수이다.)
Book(Book&& other); // 이동 생성자
Book(const Book& other); // 복사 생성자
- 복사 생성자와 이동 생성자의 차이점
- 복사 생성자는 원본을 유지하고, 이동 생성자는 원본을 유지하지 않는다.
- 예를들어, 어떤 배열에서 값을 꺼내어 사용할 때 복사생성자를 사용하면 원본이 유지된 채 값만 꺼내오고, 이동 생성자를 사용하면 원본이 유지되지 않고 원본에서 꺼내온 값이 삭제된다.
- 복사 생성자는 LValue이고, 이동생성자는 RValue이다.
🔷 복사 대입 연산자 (Assignment Operator)
원형
Enemy& operator=(const Enemy& enemy)
{
if(this != &enemy) { } // 다를 때만 복사 수행
return *this;
}
- 복사 대입 연산자는 같은 타입의 객체를 이미 생성되어 있는 객체에 값을 복사할 때 사용된다.
- 따로 복사대입 연산자를 정의하지 않으면, 컴파일러가 암시적(디폴트) 복사 대입 연산자를 생성해주는데, 이때는 모두 얕은 복사를 사용하여 참조값만 복사된다. (복사생성자와 동일한 디폴트 문제)
복사대입연산자와 복사생성자의 호출
Test t1;
Test t2(t1); // 복사생성자
Test t3 = t1; // 복사생성자
t1 = t2; // 복사대입연산자
- 객체를 생성함과 동시에 다른 객체를 복사하면 복사생성자가 호출된다.
- 이미 생성되어 있는 객체에 다른 객체를 복사하면 복사대입연산자가 호출된다.
🔷 대입 연산자
대입 연산자 (Assignment Operator)
원형
Book::Book(Book&& other);
- 대입 연산자는 변수에 값을 대입할 때 사용하는 이항 연산자이며, 피연산자들의 결합 방향은 오른쪽에서 왼쪽이다.

🔷 이동대입 연산자
원형
Book& operator=(Book&& other);
Book& Book::Operator=(Book&& other) { }
- 이동대입 연산자는 이동생성자와 같은 개념으로, 다른 개체 멤버 변수들의 소유권을 가지고오며 메모리 재할당을 하지 않는다.
사용예시
Test t1;
Test t2;
t2 = std::move(t1);
참조
http://www.tcpschool.com/cpp/cpp_conDestructor_defaultConstructor
코딩교육 티씨피스쿨
4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등
tcpschool.com
http://www.tcpschool.com/cpp/cpp_conDestructor_destructor
코딩교육 티씨피스쿨
4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등
tcpschool.com
http://www.tcpschool.com/cpp/cpp_conDestructor_copyConstructor
코딩교육 티씨피스쿨
4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등
tcpschool.com
colin's 블로그
개발 강좌 블로그
colinch4.github.io
http://www.tcpschool.com/cpp/cpp_operator_assignment
코딩교육 티씨피스쿨
4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등
tcpschool.com
https://coding-factory.tistory.com/701
[C++] 복사 생성자, 복사 대입 연산자 (+깊은 복사)
클래스 생성 시 컴파일러가 자동으로 생성해주는 함수는 생성자, 소멸자, 복사 생성자, 복사 대입 연산자 이렇게 4가지가 있으며 이번 포스팅에서 다룰 내용은 복사 대상자와 복사 대입 연산자
coding-factory.tistory.com
https://prototype-ghost.tistory.com/8
C++ 복사생성자 : 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)
안녕하세요 귀신입니다. 군대갔다오고 2년만에 대학을 다니다보니 정신없이 시간이 흘러가고 있는 것 같습니다. 그래도 오랜만에 학교 생활 하니까 기분은 좋네요 ㅎㅎ 오늘은 클래스를 공부할
prototype-ghost.tistory.com
https://velog.io/@sjongyuuu/C-%EB%B3%B5%EC%82%AC-%EC%83%9D%EC%84%B1%EC%9E%90Copy-Constructor
C++ 복사 생성자(Copy Constructor)
지난 생성자와 초기화 리스트편 포스팅에 이어 이번 포스팅에서는 복사 생성자(Copy Constructor)에 대해 다루어 보려고 한다.
velog.io