#include <iostream>
using namespace std;

class Mother
{
private:
//protected:
	int m_i;
	
public:
    Mother() // 이 default 생성자를 추가해주면 알아서 호출하기 때문에 에러가 사라짐.
        : m_in(0)
    {}
    
    Mother(const int & i_in) // Child 클래스를 만들 때에는 Mother class의 생성자도 같이 호출한다. 이 생성자만 있을 경우엔 에러 발생.
        : m_i(i_in)
    {
    	cout << "Mother Constructor" << "\n";        
    }
    
	void setValue(const int & i_in)
	{
		m_i = i_in;
	}
	
	int getValue()
	{
		return m_i;
	}
};

class Child : public Mother // 상속. Mother 클래스에 있는 것들을 사용할 수 있다. derived class라고도 함.
{
private:
    double m_d;
    
public:
    
    Child(const int & i_in, const double & d_in) // 보통 Child를 쓰는 이유가 Mother 것도 같이 쓰려고 하는 목적이기 때문에 같이 초기화해줌.
    	//: m_i(i_in), m_d(d_in) 접근이 안된다. 생성자는 메모리가 할당될 때 이렇게 해주세요~ 지 할당된 후에 복사를 해주세요가 아니기 때문에 불가능
        : Mother(i_in), m_d(d_in) // Child 생성자가 i_in을 받으면서 Mother의 생성자를 호출하면 더 깔끔하다.
    {
        //Mother::setValue(i_in);
        //m_d = d_in;
    }
    
    
    void setValue(const int & i_in, const double & d_in)
    {
        // m_i = i_in; private이라 접근이 안됨. 자식한테도 허용이 안됨. protected로 쓰면 접근 가능.
        Mother::setValue(i_in); // Mother class의 setValue를 쓰겠다 하는 방식도 가능.
        m_d = d_in;
    }
    
    void setValue(const double & d_in) // Mother class에 있는 것과 이름이 같지만, Child class에 있는 것을 우선으로 한다.
    {
        m_d = d_in;
    }
    
    double getValue()
    {
        return m_d;
    }
};



int main()
{
	Mother mother;
	mother.setValue(1024);
	cout << mother.getValue() << "\n";
    
    Child child(1024, 128);
    //child.Mother::setValue(1024); 이런식으로 쓰기도 가능
    //child.setValue(128);
    cout << child.Mother::getValue() << "\n"; //1024
    cout << child.getValue() << "\n"; // 128
	
	return 0;
}