생성자. 소멸자. 초기화리스트

보물창고·2022년 8월 15일
0

c++ basic 코드누리

목록 보기
26/50

생성자란.

: 객체 생성시 컴파일러가 자동으로 Call하는 함수.

  • 왜 사용할까?
    : 객체를 생성과 동시에 초기화하기 위함.

  • 형태
    : 클래스명과 동일한 이름을 가지고 있고, 반환하는 코드 없다.

  • 유저가 정의하지 않으면,
    : 컴파일러가 디폴트 생성자를 만들어주고, 자동적으로 호출하게 한다.

  • but , 기본생성자를 만들지 않고, 인자가 있는 생성자를 만들면?
    : 인자 없는 객체를 생성하는 코드 작성시, 컴파일러는 디폴트 생성자를 만들어주지 않는다.

  • 되도록이면 {} 직접 초기화를 사용하자.
    -> 중괄호 초기화를 하면 멤버들은 0으로 초기화됨.

  • 동적할당시 new 연산자를 사용하면, 생성자가 자동으로 호출됨.
    -> new 연산자는 메모리를 생성하면서 생성자를 호출하는 2가지 동작이 이루어짐.

  • 객체를 생성하면?
    : 객체 크기 만큼의 메모리를 할당함.
    : 생성자가 호출됨.
    : 생성자가 없으면 객체를 만들 수 없음.

malloc vs new 로 객체 생성시

  1. malloc
    : 메모리만 할당되고, 생성자는 호출되지 않음.
    :: 형변환을 해야 함.
  2. new
    : 메모리 할당하고, 생성자 호출함.

위임생성자

: 생성자에서 오버라이딩된 다른 생성자를 call하게 함.
-> 생성자의 이니셜라이저에서 다른 생성자를 call 하자.

problem

: Point 클래스와 int, int 2개를 인자로 갖는 생성자를 만들자.
그리고, 디폴트 생성자에서 x와 y값에 1,2을 초기화하는 위임생성자를 만들어라.

디폴트 생성자.

  • 개념
    : 사용자가 생성자를 한 개도 만들지 않으면, "컴파일러가 인자 없는 생성자를 제공함. "

: Point() = default;
유저가 Point() {}; 명시를 할 수 있지만, (-> 이때는 멤버 초기화되지 않은상태임.)
default를 작성하게 되면,
컴파일러에게 디폴트생성자 만들어달라고 명시하는 것임.
그리고 추가적으로 멤버들 모두 0으로 초기화된다.

소멸자.

: 객체 해제시 자동으로 call되는 함수

  • 왜 필요할까?
    : 동적할당된 메모리를 해제하는 코드를 넣어야 함.

  • raii , 즉 스마트 포인터 역할을 할 수 있게 함.
    : 다른 객체의 포인터를 privat 멤버로 놓고,
    소멸자에서 해당 객체 포인터를 해제하는 코드를 작성하면 됨.

생성자, 소멸자 호출 순서

  • 멤버를 객체로 가지고 있는 클래스의 경우, 멤버 객체의 생성자가 먼저
    호출되고 난 후, 자신의 생성자 호출함.

  • 소멸 시
    : 자신의 소멸자 호출하고, 멤버 소멸자가 호출됨.

이니셜라이저

: 객체 생성과 동시에 초기화를 하게 하는 기법

  • 이니셜라이저를 사용하지 않고, 생성자 스코프 내에서
    멤버데이터에 대입 초기화를 하는 것은 복사 대입이다.
  • 이니셜라이저를 반드시 해야하는 경우
    1) const 변수
    2) ref 변수
    3) 멤버로 객체를 가지고 있을 때
    (디폴트 생성자가 없는 타입이 멤버 데이터로 있지만, 생성자 인자가 존재할 경우.)
    : 인자를 가지고 있는 생성자만 존재할 경우...

problem

  • 클래스 Object에 참조 변수 int a를 멤버로 갖자.

  • const int b를 멤버로 갖자.

  • 3번의 경우는 아래 문제에서 진행함.

  • 클래스 Object를 객체화하지도 않았는데, 컴파일 에러가 발생함.

  • 참조변수를 위해 인자를 했지만, 좋지 않은 방법임.
    : 왜냐하면 aa는 지역변수다... ref가 받을수 있으려나..

problem

가) int x, y를 가지는 point 클래스를 만들자.
나) 디폴트 생성자는 없으며, 인자2개를 갖는 생성자가 있음.
다) point p1, p2를 멤버로 갖는 rect 클래스를 만들자.
: 생성자도 만들자.
라) 대입 초기화 , 이니셜라이저 초기화등을 하면서 필요성을 인지하라.

과정

1) point,와 rect 클래스를 만들었음.

-> 컴파일러가 현재 상태에서 봤을 때 , CRect에서 CPoint 객체의 생성자를
call 할수 없는 상태임. (디폴트가 없기 때문)

2) 그래서 CRect의 생성자에서 생성자를 직접 call하는 코드를 작성해보자.

-> 안되는 이유에 대해서, 기본적으로 멤버객체의 생성자를 먼저 call 한후에
CRect 생성자에 진입하게 되는데, CRect 진입하기 전에 멤버데이터 생성자 코드를 작성하지 않아서 발생하는 것이다.

-> 위의 코드대로 하게 되면,
(이렇게 되면, 멤버객체의 생성자를2번이나 call 하게 됨. )

3) 이니셜라이저에 옮겨보자.
: 멤버 데이터나 상속 클래스는 해당 생성자에 진입하기 전에 선처리기에서
먼저 초기화가 되는 것이므로, 반드시 이니셜라이저에서 초기화를 해야 한다

-> 이상 무!

profile
🔥🔥🔥

0개의 댓글