007. 상속(Inheritance)의 이해
I. 상속의 기본 개념
- 아래의 소스를 보자
- class Person
{
int age;
char name[20];
public:
int GetAge()const
{
return age;
}
const char* GetName() const
{
return name;
}
Person(int _age=1,char* _name = "noname")
{
age = _age;
strcpy(name, _name);
}
}; - class Student : public Person
{
char major[20];
public:
Student(char* _major)
{
strcpy(major,_major);
}
const char* GetMajor()const
{
return major;
}
void ShowData() const
{
cout<<"이름 : "<<GetName()<<endl;
cout<<"나이 : "<<GetAge()<<endl;
cout<<"전공 : "<<GetMajor()<<endl;
}
};
-
클래스들만 정의 한 것이다.
- 위에 소스를 보면 class Person이랑 class Student 두개의 클래스가 선언 되어 있다. 그런데 Student 클래스를 보면 class Student : public Person 이라고 되어있는데 이것이 Person 클래스를 public으로 상속을 받겠다는 뜻이다.
- 이제 풀 소스를 보자
- #include <iostream>
- using namespace std;
- class Person
{
int age;
char name[20];
public:
int GetAge()const
{
return age;
}
const char* GetName() const
{
return name;
}
Person(int _age=1,char* _name = "noname")
{
age = _age;
strcpy(name, _name);
}
}; - class Student : public Person
{
char major[20];
public:
Student(char* _major)
{
strcpy(major,_major);
}
const char* GetMajor()const
{
return major;
}
void ShowData() const
{
cout<<"이름 : "<<GetName()<<endl;
cout<<"나이 : "<<GetAge()<<endl;
cout<<"전공 : "<<GetMajor()<<endl;
}
}; - int main()
{
Student Kim("Computer");
Kim.ShowData();
return 0;
}
-
결과값을 찍어보자. 다음과 같은 그림으로 되어 있다고 보면 된다.
II. 상속하는 클래스의 객체 생성 및 소멸 과정
- 객체 생성 과정의 이해
- #include <iostream>
- using namespace std;
- class AAA
{
public:
AAA()
{
cout<<"AAA() Call!!"<<endl;
}
AAA(int i)
{
cout<<"AAA(int i) Call!!"<<endl;
}
}; - class BBB : public AAA
{
public:
BBB()
{
cout<<"BBB() call!"<<endl;
}
BBB(int j)
{
cout<<"BBB(int j) call!"<<endl;
}
}; - int main(void)
{
cout<<"객체 1 생성"<<endl;
BBB bbb1;
cout<<"객체 2 생성 "<<endl;
BBB bbb2(10);
return 0;
}
-
위 소스의 결과값을 보면 BBB(int j)call 는 떴는데 AAA(int i) call 은 왜 안뜨는지 이상하게 여길지도 모른다.
- 이유는 메인에서 BBB bbb2(10)으로 불렀을 때, BBB(int j)로 가지만 상속을 받아서 AAA로 갈 때는 10도 같이 넘어 가는게 아니기 때문에 디폴트생성자인 AAA()를 부르기 때문에 AAA(int i)가 결과값에 안뜨는 것이다.
- 객체 생성 과정의 적용
- #include <iostream>
- using namespace std;
- class Person
{
int age;
char name[20];
public:
int GetAge() const
{
return age;
}
const char* GetName() const
{
return name;
}
Person(int _age = 1,char* _name = "noname")
{
age= _age;
strcpy(name,_name);
}
}; - class Student : public Person
{
char major[20];
public:
Student(int _age,char* _name, char* _major)
{
age = _age;
strcpy(name,_name); - strcpy(major,_major);
}
const char* GetMajor() const
{
return major;
}
void ShowData() const
{
cout<<"이름 : "<<GetName()<<endl;
cout<<"나이 : "<<GetAge()<<endl;
cout<<"전공 : "<<GetMajor()<<endl;
}
}; - int main()
{
Student Kim(20,"Hong Gil Dong", "computer");
Kim.ShowData();
return 0;
}
-
위의 소스를 컴파일 하면 오류가 난다 어디서 나는지 보자.
- Student 클래스 안에 생성자 안에 age = _age와 strcpy(name, _name); 이 두개가 에러가 난다. 이유가 뭘까?
- 이유는 age와 name이 Person클래스에서 보면 private이기 때문에 오류가 난다. public 일경우는 오류가 날 일이 없다. 그럼 어찌 해야할까? Student클래스안에 생성자만 좀 바꾸어 주면 된다.
- Student(int _age,char* _name, char* _major) : Person(_age,_name)
{
strcpy(major,_major);
}
- 위의 소스를 보면 Student 생성자의 int _age, char* _name이 Person클래스의 생성자를 호출하는데 쓰인다.
- 객체 소멸 과정의 이해
- #include <iostream>
- using namespace std;
- class AAA
{
public:
AAA()
{
cout<<"AAA() call!"<<endl;
}
~AAA()
{
cout<<"~AAA() call!"<<endl;
}
}; - class BBB : public AAA
{
public:
BBB()
{
cout<<"BBB() call!"<<endl;
}
~BBB()
{
cout<<"~BBB() call!"<<endl;
}
}; - int main()
{
BBB bbb;
return 0;
}
-
위의 소스의 결과값을 보면 먼저 생성된것은 나중에 소멸된다.
-
- 그리고 메인에서 BBB를 호출했는데 AAA가 먼저 찍힌 이유는 BBB를 호출할때 AAA에서 상속 받았기 때문에 AAA클래스로 이동에서 AAA생성자부터 호출한 다음 BBB의 생성자를 호출한다. 그리고 소멸은 BBB가 소멸되고 AAA가 소멸된다. AAA가 소멸을 먼저 되게 하면 오류는 안띄어도 실행시 에러메시지가 가볍게 나와줄 것이다.
III. protected 멤버
-
protected 멤버의 특징이다.
- protected 멤버는 외부에서 보면 private로 보이고, 상속 관계에서 보면 public으로 보인다.
- protected 멤버는 private 멤버와 똑같다. 다만 private 멤버와 달리 상속 관계에 놓여 있는 경우에 접근을 허용할 뿐이다.
- #include <iostream>
- using namespace std;
- class Person
{
protected:
int age;
char name[20];
public:
int GetAge() const
{
return age;
} - const char* GetName() const
{
return name;
}
Person(int _age = 1,char* _name = "noname")
{
age = _age;
strcpy(name,_name);
}
}; - class Student : public Person
{
char major[20];
public:
Student(int _age,char* _name, char* _major) : Person(_age,_name)
{
strcpy(major,_major);
}
const char* GetMajor() const
{
return major;
}
void ShowData() const
{
cout<<"이름 : "<<name<<endl;
cout<<"나이 : "<<age<<endl;
cout<<"전공 : "<<major<<endl;
} - };
- int main()
{
Student Kim(20,"kim","po");
Kim.ShowData();
return 0;
}
- 위의 소스를 보면 age와 name이 protected로 되어 있다. 그렇기 때문에 class Student에서 생성자 초기화시 age와 name이 private처럼 해주면 된다. 그리고 보면 ShowData에서 name,age,major 처럼 상속관계일때 외부에서 접근이 가능하다.
IV. 세가지 형태의 상속
상속형태 | public | protected | private |
기본 클래스 | |||
public 멤버 | public | protected | private |
protected 멤버 | protected | protected | private |
private 멤버 | 접근불가 | 접근불가 | 접근불가 |
-
개념 정도만 알자
- public 상속은 public 보다 접근 권한이 넓은 것을 public으로 맞춰준다.
- protected 상속은 protected보다 접근 권한이 넓은 것을 protected으로 맞춰 준다.
- private 상속은 private보다 접근 권한이 넓은 것은 private으로 맞춰준다.
문제
이 글은 스프링노트에서 작성되었습니다.
'2. C/C++ > 02. C++' 카테고리의 다른 글
009. virtual의 원리와 다중 상속 (0) | 2008.12.07 |
---|---|
008. 상속과 다형성 (0) | 2008.12.07 |
006. static 멤버와 const 멤버 (0) | 2008.12.07 |
005. 복사생성자 (0) | 2008.12.07 |
004. 클래스의 완성 (0) | 2008.12.07 |