클래스 사이에서 상속관계 정의
기본 클래스의 속성과 기능을 파생 클래스에 물려주는것
기본 클래스에서 파생 클래스로 갈수록 클래스의 개념이 구체화
다중 상속을 통한 클래스의 재 활용성을 높임
class Student:public Person{
//person을 상속받는 Student 선언
...
};
class StudentWorker : public Student{
//Student를 상속받는 StudentWorker 선언
...
}
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
class Point{
int x, y;
public:
void set(int x,int y){ this -> x = x; this -> y = y;}
void showPoint(){
cout << "(" << x << "," << y << ")" << endl;
}
};
class ColorPoint: public Point{
string color;
public:
void setColor(string color){ this-> color = color;}
void showColorPoint();
};
void ColorPoint::showColorPoint(){
cout << color << ":";
showPoint();
}
int main(){
Point p;
ColorPoint cp;
cp.set(3,4);
cp.setColor("Red");
cp.showColorPoint();
}
파생클래스 객체 포인터(우측)를 기본클래스 객체 포인터(좌측)로 치환
int main(){
ColorPoint cp;
ColorPoint *pDer = &cp;
Point* pBase = pDep; // 업케스팅 (파생 클래스의 멤버 접근 불가)
//pBase 포인터로 기본 클래스의 public 멤버만 접근 가능
//pDer 포인터로 객체 cp의 모든 public 멤버 접근 가능
pDer -> set(3,4);
pBase -> showPoint();
pDer -> setColor("Red");
pDer -> showColorPoint();
pBase -> showColorPoint(); // 컴파일 오류
}
기본 클래스의 객체 포인터를 파생 클래스의 객체 포인터로 치환
int main(){
ColorPoint cp;
ColorPoint *pDer;
Point* pBase = &cp; //업캐스팅
//pBase 포인터로 기본 클래스의 public 멤버만 접근 가능
pBase -> set(3,4);
pBase -> showPoint();
pDer = (ColorPoint *)pBase; //다운 캐스팅, 강제 형변환 반드시 필요
//pDer 포인터로 cp의 모든 public 멤버 접근 가능
pDer -> setColor("Red");
pDer -> showColorPoint();
}
private 멤버
#include <iostream>
#include <string>
using namespace std;
class Point {
protected:
int x, y; //한 점 (x,y) 좌표값
public:
void set(int x, int y);
void showPoint();
};
void Point::set(int x, int y) {
this->x = x;
this->y = y;
}
void Point::showPoint() {
cout << "(" << x << "," << y << ")" << endl;
}
class ColorPoint : public Point {
string color;
public:
void setColor(string color);
void showColorPoint();
bool equals(ColorPoint p); };
void ColorPoint::setColor(string color) {
this->color = color;
}
void ColorPoint::showColorPoint() {
cout << color << ":";
showPoint(); // Point 클래스의 showPoint() 호출
}
bool ColorPoint::equals(ColorPoint p) {
if(x == p.x && y == p.y && color == p.color) // 접근 가능
return true;
else
return false;
}
int main() {
Point p; // 기본 클래스의 객체 생성
p.set(2,3);
p.x = 5; //오류 접근 못함 : protected 영역
p.y = 5; //오류 접근 못함 : protected 영역
p.showPoint();
ColorPoint cp; // 파생 클래스의 객체 생성
cp.x = 10; // 오류 접근 못함 : protected 영역
cp.y = 10; // 오류 접근 못함 : protected 영역
cp.set(3,4);
cp.setColor("Red");
cp.showColorPoint();
ColorPoint cp2;
cp2.set(3,4);
cp2.setColor("Red");
cout << ((cp.equals(cp2))?"true":"false");
}
파생 클래스가 생성 될 때:
소멸자 실행 순서 : 역순
파생 클래스의 소멸자가 먼저 소멸 되고 기본 클래스 소멸자가 나중에 실행
상속 선언 시 public, private, protected의 3가지 중 하나 지정
기본 클래스의 멤버의 접근 속성을 어떻게 계승할지 지정
#include <iostream>
using namespace std;
class Base {
int a;
protected:
void setA(int a) { this->a = a; }
public:
void showA() { cout << a; }
};
class Derived : private Base { //private 계승으로 사용 불가
int b;
protected:
void setB(int b) { this->b = b; }
public:
void showB() { cout << b; }
};
int main() {
Derived x;
x.a = 5; // ① Base의 private 멤버로 접근 불가
x.setA(10); // ② private 계승으로 접근 불가
x.showA(); // ③ private 계승으로 접근 불가
x.b = 10; // ④ 외부 함수 접근으로 접근 불가
x.setB(10); // ⑤ 외부 함수 접근으로 접근 불가
x.showB(); // ⑥ public으로 접근 가능
}
#include <iostream>
using namespace std;
class Base {
int a;
protected:
void setA(int a) { this->a = a; }
public:
void showA() { cout << a; }
};
class Derived : protected Base {
int b;
protected:
void setB(int b) { this->b = b; }
public:
void showB() { cout << b; }
};
int main() {
Derived x;
x.a = 5; // ① Base 의 private 멤버
x.setA(10); // ② protected 계승 이지만 외부 함수 접근으로 사용 불가
x.showA(); // ③ protected 계승 이지만 외부 함수 접근으로 사용 불가
x.b = 10; // ④ 외부 함수 접근으로 사용 불가
x.setB(10); // ⑤ 외부 함수 접근으로 사용 불가
x.showB(); // ⑥ public 으로 사용 가능
}
#include <iostream>
using namespace std;
class Base {
int a;
protected:
void setA(int a) { this->a = a; }
public:
void showA() { cout << a; }
};
class Derived : private Base {
int b;
protected:
void setB(int b) { this->b = b; }
public:
void showB() {
setA(5); // ① private 계승으로 자신은 사용가능
showA(); // ② private 계승으로 자신은 사용가능
cout << b;
}
};
class GrandDerived : private Derived {
int c;
protected:
void setAB(int x) {
setA(x); // ③ 컴파일 오류
showA(); // ④ 컴파일 오류
setB(x); // ⑤
}
};
class MP3 {
public:
void play();
void stop();
};
class MobilePhone {
public:
bool sendCall();
bool receiveCall();
bool sendSMS();
bool receiveSMS();
};
class MusicPhone : public MP3, public MobilePhone { // 다중 상속 선언
public:
void dial();
};
void MusicPhone::dial() {
play(); // mp3 음악을 연주시키고
sendCall(); // 전화를 건다.
}
int main() {
MusicPhone hanPhone;
hanPhone.play(); // MP3의 멤버 play() 호출
hanPhone.sendSMS(); // MobilePhone의 멤버 sendSMS() 호출
}
기본 클래스 멤버의 중복 상속
다중 상속으로 인한 기본 클래스 멤버의 중복 상속 해결
class in : virtual public BaseIO{ // in 클래스는 BaseIO 클래스를 가상 상속함
}
class out : virtual public BaseIO{// out 클래스는 BaseIO 클래스를 가상 상속함
}