상속(Inheritance)
2025. 3. 28. 00:00ㆍProgramming Languages/C++
5.5 상속(Inheritance)
5.5.1 상속의 기본 개념
상속은 기존 클래스(기본 클래스/부모 클래스)의 특성을 새 클래스(파생 클래스/자식 클래스)가 물려받는 메커니즘입니다:
#include <iostream>
#include <string>
// 기본 클래스
class Person {
protected:
std::string name;
int age;
public:
Person(const std::string& n, int a) : name(n), age(a) {}
void introduce() const {
std::cout << "이름: " << name << ", 나이: " << age << std::endl;
}
};
// 파생 클래스
class Student : public Person {
private:
std::string school;
double gpa;
public:
Student(const std::string& n, int a, const std::string& s, double g)
: Person(n, a), school(s), gpa(g) {}
void study() const {
std::cout << name << "이(가) " << school << "에서 공부합니다." << std::endl;
}
void showGPA() const {
std::cout << "학점: " << gpa << std::endl;
}
};
int main() {
Person person("홍길동", 30);
person.introduce();
Student student("김철수", 20, "서울대학교", 3.8);
student.introduce(); // 기본 클래스에서 상속받은 메서드
student.study(); // 파생 클래스의 메서드
student.showGPA(); // 파생 클래스의 메서드
return 0;
}
5.5.2 상속 접근 지정자
상속 시 사용할 수 있는 세 가지 접근 지정자:
- public 상속: 기본 클래스의 public 멤버는 파생 클래스에서도 public, protected 멤버는 protected로 유지
- protected 상속: 기본 클래스의 public, protected 멤버 모두 파생 클래스에서 protected로 변경
- private 상속: 기본 클래스의 public, protected 멤버 모두 파생 클래스에서 private로 변경
// public 상속
class PublicDerived : public Base {
// Base의 public 멤버 → PublicDerived의 public 멤버
// Base의 protected 멤버 → PublicDerived의 protected 멤버
// Base의 private 멤버 → 접근 불가
};
// protected 상속
class ProtectedDerived : protected Base {
// Base의 public 멤버 → ProtectedDerived의 protected 멤버
// Base의 protected 멤버 → ProtectedDerived의 protected 멤버
// Base의 private 멤버 → 접근 불가
};
// private 상속
class PrivateDerived : private Base {
// Base의 public 멤버 → PrivateDerived의 private 멤버
// Base의 protected 멤버 → PrivateDerived의 private 멤버
// Base의 private 멤버 → 접근 불가
};
5.5.3 다중 상속(Multiple Inheritance)
C++에서는 클래스가 여러 기본 클래스로부터 상속받을 수 있습니다:
#include <iostream>
#include <string>
// 첫 번째 기본 클래스
class Animal {
protected:
std::string name;
public:
Animal(const std::string& n) : name(n) {}
void eat() const {
std::cout << name << "이(가) 먹고 있습니다." << std::endl;
}
};
// 두 번째 기본 클래스
class Vehicle {
protected:
int wheels;
public:
Vehicle(int w) : wheels(w) {}
void move() const {
std::cout << wheels << "개의 바퀴로 움직입니다." << std::endl;
}
};
// 다중 상속
class Horse : public Animal {
public:
Horse(const std::string& n) : Animal(n) {}
void gallop() const {
std::cout << name << "이(가) 달립니다." << std::endl;
}
};
class Bird : public Animal {
public:
Bird(const std::string& n) : Animal(n) {}
void fly() const {
std::cout << name << "이(가) 날아갑니다." << std::endl;
}
};
// 다중 상속 예제
class Pegasus : public Horse, public Bird {
public:
Pegasus(const std::string& n) : Horse(n), Bird(n) {}
};
int main() {
Pegasus pegasus("페가수스");
// 다중 상속으로 인한 모호성
// pegasus.eat(); // 오류: 'eat' 멤버가 'Horse'와 'Bird' 모두에서 발견됨
// 범위 지정 연산자로 모호성 해결
pegasus.Horse::eat();
pegasus.gallop();
pegasus.Bird::fly();
return 0;
}
다중 상속의 문제점:
- 다이아몬드 문제(Diamond Problem): 두 기본 클래스가 같은 부모 클래스를 상속할 때 발생
- 모호성: 동일한 이름의 메서드나 멤버가 여러 기본 클래스에 존재할 경우
5.5.4 가상 상속(Virtual Inheritance)
다이아몬드 문제를 해결하기 위한 방법:
#include <iostream>
#include <string>
// 최상위 기본 클래스
class Animal {
protected:
std::string name;
public:
Animal(const std::string& n) : name(n) {
std::cout << "Animal 생성자 호출" << std::endl;
}
void eat() const {
std::cout << name << "이(가) 먹고 있습니다." << std::endl;
}
};
// 가상 상속을 사용한 중간 클래스
class Mammal : virtual public Animal {
public:
Mammal(const std::string& n) : Animal(n) {
std::cout << "Mammal 생성자 호출" << std::endl;
}
void breathe() const {
std::cout << name << "이(가) 폐로 숨을 쉽니다." << std::endl;
}
};
// 가상 상속을 사용한 또 다른 중간 클래스
class WingedAnimal : virtual public Animal {
public:
WingedAnimal(const std::string& n) : Animal(n) {
std::cout << "WingedAnimal 생성자 호출" << std::endl;
}
void flap() const {
std::cout << name << "이(가) 날개를 펄럭입니다." << std::endl;
}
};
// 다이아몬드 상속 구조의 맨 아래 클래스
class Bat : public Mammal, public WingedAnimal {
public:
Bat(const std::string& n) : Animal(n), Mammal(n), WingedAnimal(n) {
std::cout << "Bat 생성자 호출" << std::endl;
}
};
int main() {
std::cout << "박쥐 객체 생성:" << std::endl;
Bat bat("브루스");
// 가상 상속으로 모호성 해결
bat.eat(); // Animal::eat() 호출, 모호성 없음
bat.breathe(); // Mammal::breathe() 호출
bat.flap(); // WingedAnimal::flap() 호출
return 0;
}
'Programming Languages > C++' 카테고리의 다른 글
| 챕터5. 실습 문제 (0) | 2025.03.28 |
|---|---|
| 다형성(Polymorphism) (0) | 2025.03.28 |
| 객체 생성과 수명 주기 (0) | 2025.03.28 |
| 생성자와 소멸자 (0) | 2025.03.28 |
| 캡슐화와 접근 지정자 (0) | 2025.03.28 |