상속의 개념
C++에서 상속은 객체 지향 프로그래밍(OOP)의 중요한 개념 중 하나로, 기존 클래스(부모 클래스 또는 기본 클래스)를 기반으로 새로운 클래스(자식 클래스 또는 파생 클래스)를 만드는 과정을 의미합니다. 상속을 사용하면 코드를 재사용하고, 클래스 간의 계층 구조를 구축하여 프로그램을 구성하고 확장하기 쉬워집니다. 다음은 C++에서 상속에 관한 주요 개념들입니다:
1. 부모 클래스 (Base Class 또는 Superclass): 상속의 기초가 되는 클래스를 말합니다. 이 클래스는 이미 정의된 멤버 변수와 멤버 함수를 가지고 있습니다.
2. 자식 클래스 (Derived Class 또는 Subclass): 부모 클래스에서 상속받은 멤버 변수와 멤버 함수를 가지며, 자체적으로 새로운 멤버 변수와 멤버 함수를 추가할 수 있는 클래스입니다.
3. 상속 관계: 자식 클래스는 부모 클래스의 멤버를 상속받습니다. 이는 자식 클래스가 부모 클래스의 모든 멤버 변수와 멤버 함수를 사용할 수 있다는 의미입니다.
4. 접근 제어 지시자 (Access Control Specifiers): C++에서는 상속된 멤버 변수와 멤버 함수의 접근 권한을 조절하기 위해 `public`, `private`, `protected`와 같은 접근 제어 지시자를 사용합니다. 각각의 접근 제어 지시자는 상속된 멤버에 대한 접근 권한을 다르게 설정합니다.
5. 상속 형태: C++에서는 클래스간의 상속 관계를 설정할 때 `public`, `private`, `protected` 키워드를 사용하여 상속 형태를 결정합니다.
- `public` 상속: 부모 클래스의 `public` 멤버는 자식 클래스에서 `public`으로 유지됩니다. `protected` 멤버는 `protected`로, `private` 멤버는 자식 클래스에서 접근할 수 없습니다.
- `protected` 상속: 부모 클래스의 `public` 및 `protected` 멤버는 자식 클래스에서 `protected`로 상속됩니다. `private` 멤버는 자식 클래스에서 접근할 수 없습니다.
- `private` 상속: 부모 클래스의 모든 멤버는 자식 클래스에서 `private`으로 상속됩니다.
상속을 사용하면 코드 재사용성이 높아지며, 계층 구조를 통해 복잡한 시스템을 구성하고 유지 보수하기 쉬워집니다. 자식 클래스는 부모 클래스의 특성을 확장하거나 수정할 수 있으므로 프로그램의 요구 사항에 맞게 클래스를 조정할 수 있습니다.
클래스 상속과 객체
- 상속은 클래스 간의 관계를 표현하며, 부모 클래스에서 자식 클래스로 멤버 변수와 멤버 함수를 공유할 수 있게 합니다. 자식 클래스는 부모 클래스의 모든 멤버를 자신의 것처럼 사용할 수 있습니다.
- 예를 들어, 다음은 C++에서의 상속 예제입니다:
class Animal {
public:
void eat() {
cout << "동물이 먹는다." << endl;
}
};
class Cat : public Animal {
public:
void meow() {
cout << "고양이가 울부짖는다." << endl;
}
};
여기서 `Cat` 클래스는 `Animal` 클래스를 상속하고, `Cat` 객체는 `eat()` 함수를 호출할 수 있습니다.
상속과 객체 포인터
- 객체 포인터를 사용하면 부모 클래스 포인터로 자식 클래스 객체를 가리킬 수 있습니다. 이를 통해 다형성을 구현할 수 있으며, 여러 자식 클래스 객체를 동일한 부모 클래스 포인터로 관리할 수 있습니다.
- 다형성을 이용하면 런타임 시에 어떤 클래스의 멤버 함수가 호출될지 결정됩니다.
상속과 생성자, 소멸자
- 자식 클래스의 생성자에서 부모 클래스의 생성자를 호출하여 부모 클래스의 초기화를 수행해야 합니다. 이것은 초기화 리스트(initialization list)를 사용하여 수행됩니다.
- 소멸자 역시 자식 클래스에서 부모 클래스의 소멸자를 호출하여 메모리 누수를 방지합니다.
class Animal {
public:
Animal() {
cout << "Animal 생성자 호출" << endl;
}
~Animal() {
cout << "Animal 소멸자 호출" << endl;
}
};
class Cat : public Animal {
public:
Cat() {
cout << "Cat 생성자 호출" << endl;
}
~Cat() {
cout << "Cat 소멸자 호출" << endl;
}
};
상속의 종류
- `public`, `protected`, `private` 상속의 종류는 멤버 변수와 멤버 함수의 접근 권한을 결정합니다.
- `public` 상속은 부모 클래스의 `public` 멤버를 자식 클래스로 그대로 공개합니다. `protected` 상속은 `public` 멤버를 `protected`로, `private` 상속은 `public` 멤버를 `private`로 변경합니다.
다중 상속
- 다중 상속은 하나 이상의 부모 클래스로부터 상속을 받는 것을 의미합니다. 예를 들어, 클래스 A와 클래스 B를 상속받는 클래스 C는 다중 상속을 사용한 예입니다.
- 다중 상속은 여러 클래스로부터 특성을 상속받을 수 있지만, 다이아몬드 상속 문제와 같은 모호성을 발생시킬 수 있으므로 주의가 필요합니다.
가상 상속
- 가상 상속은 다이아몬드 상속 문제를 해결하기 위한 메커니즘으로, 중복 상속 시 발생하는 모호성을 제거합니다.
- 가상 상속은 `virtual` 키워드를 사용하여 선언하며, 가상 상속된 클래스의 인스턴스는 하나만 존재하게 됩니다. 이를 통해 중복된 부모 클래스의 인스턴스를 방지할 수 있습니다.