class Parent
{
private:
int m_value_1;
public:
Parent()
:
m_value_1(10)
{}
};
class Child : public Parent
{
private:
float m_value_2;
public:
Child()
:
m_value_2(20.2f)
{}
};
이렇게 만들었을 떄의 메모리 구조가 어떻게 되냐하면은
상속받으면 이런 메모리 구조임
child안에는.
부모의 private으로 선언되어 있는 필드는 부모 객체만 접근이 가능하다.
상속받은 객체는 부모의 private필드에 접근 못한다.
메모리 구조가 사진처럼 되어있어도.
그래서 자식만 접근이 가능하게 해주고싶다면은
를 사용해주면된다.
그리고 상속을 받을 경우 메모리 구조가
이렇게 순차적으로 잡히게 된다.
이게 중요한 개념이다.
부모 생성자 -> 자식 생성자 순서이다.
소멸자 호출 순서는 파생 클래스 -> 기반 클래스 순서이다.
부모의 멤버변수를
자식의 생성자안에서 "초기화" 해줄 수 없다.
각자의 생성자로 각자 초기화를 해주도록 하자.
생성자 함수 안에서의 부모 클래스의 멤버 변수를 값을 넣어 주는 작업은?
':' 에서는 초기화 부분이다. 다른 것이다.
setFloat랑 뭐가 다르냐? 이말이다.
이것은 지금 생성자에서의 Initialize부분이다.
부모 -> 자식이다. 근데
자식 클래스의 객체를 만들면
이 객체의 주체는 "자식 클래스"이기 때문에 자식 클래스의 "생성자"가 먼저 호출이 된다.
로그를 찍어보아도, 부모 -> 자식 맞는데
자식 생성자가 먼저 호출이 된다는 말인데, 이게 무슨 말인가 하면은
실제 주체는 Child이다. 단지 얘가 Parent라는 클래스를 상속 받았을 뿐이다.
그러면 먼저 호출 되어야하는 생성자는 "자식"쪽이다.
그리고 이 자식의 "부모"쪽은 누구보고 (생성자)를 호출하라고 넘겨 주어야 하나?
Parent쪽 생성자를 통해서 초기화를 하라고 "호출"을 해주어야한다는 말이다.
그러니까 자식 클래스 생성자 호출 -> 부모쪽 생성자로 감 -> 부모쪽에서 생성자 호툴 -> 자식 생성자 호출
지금 FuncB 호춣하면
FucB() 호출 -> FuncA() 호출 -> FuncA() 끝나고 -> FuncB() 끝남.
그러면 이것을 보고 FuncB가 먼저 호출 되었다고 말을 하나??
FuncB가 호출이 되었는데 그다음에 바로 FuncA를 호출 한 것이다.
그러니까 생성자 호출 순서가 아니라 생성자 "실행 순서"이다.
그래서
지금 이부분에서 Child에서의 생성자 초기화 부분에서 뭐가 "생략"이 되어 있냐면은
Parent 생성자 호출이 생략되어있는 것이다.
그래서 "부모"가 먼저 초기화 된다는 말이 이제서야 맞는 말인 것이다❗
이렇게 바꾸면 어케될까?
이렇게 꺼꾸로 적어주어도 무조건 부모가 먼저 호출됨.
이런 클래스 객체 만들면 위로 쭉 올라갔다가 아래려 내려오는 식임.
자식 클래스객체를 만들면
자식 생성자 -> 부모 생성자 이렇게 가는데 부모에 생성자가 오버로딩 되어있으면
뭘 호출을 할까??
당연히 "기본 생성자"를 호출을 한다.
딱히 명시해 주지 않는다면.
명시해줄려면 이렇게 적어 주어야함.