// 상속과 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); }
};