title: “C++ 12. 상속” categories:

  • CspecialCharspecialChar

    #C++ 12. 상속 : 네이버 블로그

상속이란…음 쉽게 생각해보자

​

상속이란 부모에게 무엇을 받는 것이 아닌가?

마찬가자로 클래스도 상속될 수 있다

​

그럼 한가지 생각해보자 부모 클래스와 자식 클래스중 어떤 클래스가 상위인가?

당연히 부모 클래스가 상위인것을 알 수 있다

​

그렇다면 자식 클래스는 부모 클래스에 속하는가?라는 질문에 대답할 수 있다

자식클래스는 부모 클래스에 속한다

​

예를 들어 People 클래스가 있다 하자

이 클래스는 맴버로 string name을 가진다

​

또 child 클래스가 있다 하자

이 클래스는 맴머로 string school을 가진다

​

그럼 child가 people을 상속 받는다고 한다면

부모 클래스인 people을 포함하므로 name을 사용할 수 있다

​

​

상속은 클래스를 선언할 때 설정한다

class 파생클래스명 : 상속접근지정 기본클래스명

child를 생각하면

class child:public people로 쓸 수 있다

​

여기서 기본 클래스는 부모 클래스(people)이고 파생클래스는 자식클래스(child)이다

​

​

:public은 상속접근지정자로 public,protected,private가 있다

public으로 받으면 기본 클래스의 맴버를 접근지정없이 그대로 받는다. 접근지정이 public으로 바뀌는 것이 아닌 그대로 받는 것임에 주의하라

​

protected는 기본 클래스의 맴버를 protected로 받는다

​

private는 기본 클래스의 맴버를 private로 받는다

​

​

​

​

상속은 중첩해서 쓸 수도 있다

class A;

class B:public A;

class C:public B;

이렇게 있다면 C는 A와 B의 맴버를 모두 가지고 있다

​

​

또C++에서는 다중 상속도 가능하다

class A;

class B;

가 있을때

class C:public A,public B;를 하면 상속이 가능하다

​

​

다중 상속은 문제점이 있는데 A,B가 같은 클래스를 상속받으면 맴버가 같기 때문에 오류가 나게 된다

class Base;

class A:public Base;

class B:public Base ;

class C:public A,public B;

위와 같이 A,B는 Base를 상속받는다.

서로 같이 상속을 받으니 각각 부모를 가지고 있고 이 A,B가 C에 상속하게 되면 C는 같은 고조부(?)가 둘이게 된다

​

이런 맴버 중복의 문제를 해결하기 위해 가상 상속을 쓸 수 있다

class A:virtual public Base;

class B:virtual public Base;

를 사용하면 A,B는 생성하면서 자신의 기본 클래스가 이미 생성되었는가를 확인한다

​

즉 생성이 되어있으면 생성하지 않는다

그러므로 Base는 하나가 될 수 있다

​

​

​

​

다음 설명할 내용은 업캐스팅과 다운캐스팅입니다

나중에 설명을 함으로 지금은 넘어가도 됩니다

그래도 설명을 하자면

#include
#include
using namespace std;
class people {
 string name;
public:
 people() {

 }
 void setname(string n) {
 name = n;
 }
};
class student:public people {
 string school;
public:
 student() {
 }
 void setschool(string s) {
 school = s;
 }
};
int main() {
 student A;
 student \*pDer = &A
 people \*pBase = &A

 pDer->setname("L");
 pDer->setschool("H");

 pBase->setname("L");

}

클래스는 두개가 있습니다 people이랑 student입니다

people은 name을 설정하는 public맴버 setname을 가지고

student는 school을 설정하는 public 맴버 setschool을 가지고 있습니다

​

이제 메인으로 넘어가면

student A //A를 선언합니다. A에는 people이 포함되겠지요(상속받으니깐)

student *pDer=&A //A의 주소를 pDer에 저장합니다. pDer은 student객체 포인터

​

그럼 pDer이 가지는 맴버는 무엇이 있을까요?

A가 가지고 있는 setname이랑 setschool이 있습니다

​

만약 여기서 A내의 people객체만 쓰고싶다면?

people *Base //기본 클래스인 people 객체 포인터를 생성합니다

Base=&A를 함으로써 student를 가진 A를 people 객체만을 가진 Base로 넣습니다

​

그럼 Base만 가지고 있는 people만 데이터가 채워지게 됩니다

그럼 Base는 people객체만 가지게 되고 맴버는 setname뿐이지요(people맴버)

​

이렇게 파생클래스가 가지고 있는 기본클래스의 내용을 사용하는 것을 업 캐스팅이라고 합니다

나름 정리하자면 축소?

​

​

​

​

업도 있으면 다운도 있겠지요

다운 캐스팅은 확장이라고 생각할 수도 있습니다

​

코드는 main안의 내용만 바꿨습니다

student A;
 people \*pBase = &A
 pBase->setname("L");

 student \*pDer;
 pDer = (student \*)pBase;



 pDer->setname("L");
 pDer->setschool("H");

main만 설명하면

일단 student A로 선언됩니다

그리고 이 A를 업캐스팅한 포인터 *pBase를 선언합니다

*pBase people의 내용만 가지고 있지요

즉 업캐스팅 된ㄷ *pBase는 people의 맴버 setname만 사용할 수 있습니다

​

이후 student *pDer이 선언됩니다

pDer=(student *)pBase

이부분이 중요한데

pDer은 student이므로 people의 맴버도 포합합니다

pBase의 people맴버만 전달하기 위해서는 형변환(student *)를 사용해야 합니다

​

즉 작아진 student를 people을 포합하는 객체 포인터를 만드려면

people+student를 해야겠지요

그래서 student를 만들고 거기에 형변환으로 student로 맞춰 pBase의 people부분만 넘깁니다

​

이해…하셨나요?

이후에 나오니깐 그때 한번 더 설명하겠습니다

​

​

​

​

​

업데이트: