클래스 정의, 메서드 정의, 스택과 프리스토어에서 객체를 생성해서 사용하는 방법
생성자 작성방법 디폴트 생성자, 컴파일러가 생성하는 생성자, 생성자 포기자, 복제 생성자, 초기자 리스트 생성자,
소멸자, 대입 연산자등을 비롯한 클래스와 객체의 핵심 개념을 배운다
메서드를 호출하면 메서드가 속한 객체의 포인터가 숨겨진 매개변수 형태로 전달됨 this
8.3 객체의 라이프 사이클
생성, 소멸, 대입 세 단계로 구성됨
객체 생성
- 스택에 생성될 객체는 선언하는 시점에 생성, 스마트 포인터나 new사용할 때는 직접 공간을 할당해서 생성
객체가 생성될 때 그 객체에 포함된 객체도 함께 생성됨
선언과 동시에 초깃값을 설정할 수 있고 이 작업은 생성자라는 특수한 메서드에 코드를 작성해 처리
아무런 인수 없이 호출할 수 있는 생성자를 디폴트 생성자라고 부름
# 생성자를 직접 호출하면 안된다. 선언문과 분리해서 초기화 하려해도 안된다
생성자를 직접 호출하면 내부적으로 임시 객체가 만들어져 의도한 객체의 초기화가 제대로 되지 않는다
동적할당할 때는 이렇게
오버로딩으로 인수의 개수나 타입이 서로 다른 생성자 여러개를 만들어놓을 수도 있다.
생성자를 하나라도 만들어두면 디폴트 생성자를 자동으로 만들어 주지 않으므로 주의
C++11 이후에는 이런식으로 할일 없는 디폴트 생성자를 컴파일러가 만들어주도록 명시할 수 있다
명시적 삭제 생성자도 있다
디폴트 생성자가 생기면 안되는 경우 default처럼 delete를 넣어주면 디폴트 생성자를 생성하지 않는다
데이터 멤버를 생성자 안에서만 초기화 할 수 있는것은 아니다
생성자 초기자, 멤버 초기자 리스트를 제공한다
매우 편함. 각 항목을 쉼표로 구분하면 됨
생성자 초기자로 데이터 멤버를 초기화 하는방식은 생성자 안에서 데이터멤버를 초기화 하는것과는 다름
C++에서 생성자를 호출하는시점은 객체를 구성하는 데이터 멤버를 모두 생성하고 나서 생성자를 호출함.
하지만 생성자 초기자를 이용하면 데이터 멤버를 생성하는 과정에서 초깃값을 설정할수 있음
-> 훨씬 효율적
이 차이 때문에 반드시 생성자 초기자로 초기화 해야 하는 경우들이 있음
const 데이터 멤버 <- 한번 생성되면 값 변경이 불가하므로 생성자에서 초기화 하려하면 안됨
레퍼런스 데이터 멤버<- 가리키는 대상이 없는 레퍼런스는 생성 불가
디폴트 생성자가 정의되지 않은 객체 데이터 멤버<- 데이터 멤버가 생성될때 객체의 경우 생성자가 호출되므로
객체가 다른 객체의 데이터 멤버로 들어가 있을경우, 생성자가 없으면 에러가 남.
객체가 생성될때 데이터 멤버가 만들어지는 시점에서 각각의 데이터 멤버의 생성자가 호출되기 때문
C++에서 데이터 멤버는 생성자 초기자에 나온 순서가 아니라 클래스 정의에 나온 순서대로 초기화 되니 주의
복제 생성자
C++는 다른 객체와 똑같은 객체를 생성하는특수 생성자인 복제 생성자를 제공
원본 객체에 대한 const 레퍼런스를 인수로 받음. 리턴값 없음
대부분의 경우 컴파일러가 기본으로 생성해주는 복제 생성자를 그대로 쓰면 됨
함수나 메서드에 객체를 레퍼런스로 전달하면 복제 연산으로 인한 오버헤드를 줄일 수 있음
#원본 객체를 수정할 수 있는 상태가 되니 const를 붙여줍시다
복제 생성자도 명시적으로 삭제해버릴 수 있음
초기자 리스트 생성자
initializer_list<T>를 첫 번째 매개변수로 받고, 다른 매개변수는 없거나 디폴트 값을 가진 매개변수를 추가로 받는 생성자
위임 생성자
같은 클래스의 생성자끼리 서로 호출하는 것
반드시 생성자 초기자에서 호출해야 하며 리스트 안에 멤버 초기자만 적어야 함
재귀적으로 호출되지 않도록 주의
8.3.2 객체 제거
객체가 제거되는 과정은 먼저 객체의 소멸자를 호출 한 후 할당 받은 메모리를 반환한다.
소멸자에 객체를 정리하는 작업을 구체적으로 지정할 수 있다.
소멸자를 직접 정의하지 않으면 컴파일러가 만들어줌. 이를 이용해 멤버마다 소멸자를 재귀적으로 호출하며 객체를 제거할 수 있다.
스택 객체는 현재 실행하던 함수, 메서드 또는 코드 블록이 끝날 때와 같이 스코프를 벗어날 때 자동으로 제거된다.
스택 객체가 제거되는 순서는 선언 및 생성 순서와 반대<- 선입후출 스택
동적할당한 객체는 자동으로 제거되지 않으므로 주의
객체의 값을 다른 객체에 대입할 수 있다.
복제는 객체를 초기화할때만 적용되므로 대입과는 조금다름
복제한 객체도 사라지지 않기 때문에 이동과도 다름
대입연산자는 복제 생성자와 비슷하지만 다르다
1. 복제 생성자는 초기화 할때 단 한번만 호출됨, 대입 연산자는 객체에 이미 할당된 값을 덮어씀
2. C++는 객체에 자기 자신을 대입할 수 있다.
대입연산자 또한 명시적으로 삭제할 수 있다.
사용자가 선언한 복제 대입 연산자나 소멸자가 있으면 기본을 자동으로 생성해주지 않음
리턴값이 객체인 경우?
string의 복제 생성자를 호출해서 이름없는 임시 string을 생성
s1에 대입 연산자를 호출하여 대입
임시 string 삭제
~428p
'전문가를 위한 C++' 카테고리의 다른 글
2025/03/07 ch.09 클래스와 객체 완전 정복 (0) | 2025.03.07 |
---|---|
2025/03/06 ch.09 클래스와 객체 완전 정복 (0) | 2025.03.06 |
2025/03/04 ch.07 전문가답게 C++ 코딩하기 (0) | 2025.03.04 |
2025/03/03 ch.07 전문가답게 C++ 코딩하기 (0) | 2025.03.03 |
2025/03/02 ch.06 재사용을 고려한 설계 (0) | 2025.03.02 |