// 상속과 static
class Parent
{
public:
        static int x;
};
int Parent::x = 0;
class Child : public Parent
{
};
void main()
{
        Parent::x = 10;
        Child::x  = 20; //될까??
        cout << Parent::x << endl; // 얼마?? 20 부모자식이모두공유.!!
}
// 상속과생성자
class Parent
{
public:
        Parent() {}      // 1
        Parent(int a) {} // 2
};
class Child : public Parent
{
public:
// 3 컴파일러가 Parent()를 자동으로 생성해서 부모디폴트를 호출한다.
        Child(int a) : Parent(a) {} // 4
};
void main()
{
        Child c(1);    // 1- 4 주의부모는항상default 생성자호출
}
// protected 생성자의미: 자신을만들수없지만자식은만들수있다.!!!!
class Animal
{
protected:
        Animal() {}
};
class Dog : public Animal
{
public:
        Dog() {}
};
void main()
{
        Animal a;
   // protected로 감싸주면 현실세계를 반영 할 수 있다. 동물은 만들지 못하지만 개는 만든다.
}
// 접근변경자- 언제사용하는가? 자주나오지는않지만알아둘필요가있다.
class Parent
{
private:       int a;
protected:     int b;
public:        int c;
};
class Child : public Parent
{
        int a;  // 메모리에있지만접근불가.
        int b;
        int c;
};
// STL에 linked list가 있다. - 그런데 stack이 없다고 가정
// Adapter Design Pattern : 임의의클래스의interface(함수이름)을변경해서
//                         다른클래스처럼보이게하는기법.
// private 상속: 구현을물려받지만interface는물려받지않겠다.
#include <list>
// 부모의 가상함수를 재정의 해 주고 싶을 때에는 상속을 통하여 한다.
class Stack : private list<int>
{
public:
    // 부모인list를재사용한다.
        void Push( int a )     { push_back(a);  }
        void Pop()             { pop_back();  }      // 제거만한다.
        int  top()             { return back(); }   // 리턴만한다.
};
{
        Stack s;
        s.Push(10);
   // s.push_front(10);
   // 이 순간 Stack은 망가지게 된다. private 상속을 통해 막아버리자.
}
// 하지만  상속보다는 포함을 사용한 Adapter가 훨씬 좋은 기법이다.
class Stack
{
        list<int> st;
public:
        void Push( int a ) { st.push_back(a); }
};
