[C++] 클래스 상속(inheritance)
상속
Super, Delived, Base, Child, 부모클래스, 자식클래스 등으로 불리는 기능들을 의미한다.
클래스 선언부에 : 를 이용하여 상속을 알린다.
자식클래스는 부모클래스를 상속받아 부모클래스의 멤버변수, 멤버함수를 사용할 수 있는 권한을 가진다.
이 권한은 private, protected, public 에 따라 사용할 수 있는 권한이 다르다.
class Car
{
private:
int lotNumber;
protected:
int Price;
int GetLotNumber();
};
int Car::GetLotNumber()
{
return lotNumber;
}
class SportCar : public Car
{
public:
void ShowCarPrice();
void ShowLotNumber();
};
void SportCar::ShowCarPrice()
{
std::cout << Price << std::endl;
}
void SportCar::ShowLotNumber()
{
std::cout << GetLotNumber() << std::endl;
}
위는 Car를 public 상속을 받아 SportCar Class를 생성한 내용이다.
부모클래스의 private에 있는 멤버변수, 함수들은 상속받아도 직접 접근이 불가능하여 GetLotNumber라는 protected함수를 생성하여 접근하였다.
protected는 자식이 접근할 수 있으나 클래스 외부에서는 직접 접근이 불가능하다.
클래스의 생성자
자식클래스의 생성자가 호출되는 도중 부모클래스의 생성자가 자동으로 호출된다.
class Car
{
private:
int lotNumber;
public:
Car();
};
Car::Car()
{
std::cout << "Car 생성자 호출" << std::endl;
}
class SportCar : public Car
{
public:
SportCar();
};
SportCar::SportCar()
{
std::cout << "SportCar 생성자 호출" << std::endl;
}
int main()
{
// 자식클래스의 생성자 호출
SportCar myCar;
}
부모클래스의 생성자는 자식클래스보다 항상 먼저 실행된다.

이렇기 때문에 자식클래스 생성자 호출 시 반드시 부모클래스가 호출할 수 있는 생성자가 존재해야 한다.
class Car
{
private:
int lotNumber;
public:
Car(int Number) : lotNumber(0)
{
std::cout << "Car 생성자 호출" << "Number : " << Number << std::endl;
}
};
class SportCar : public Car
{
public:
SportCar(int number);
};
SportCar::SportCar(int number)
{
std::cout << "SportCar 생성자 호출" << std::endl;
}
위 코드는 SportCar의 생성자 부분에서 컴파일 에러가 발생한다.

class Car
{
private:
int lotNumber;
public:
Car() : lotNumber(0) { std::cout << "Car 디폴트 생성자 호출" << std::endl; }
Car(int Number) : lotNumber(0)
{
std::cout << "Car 생성자 호출" << "Number : " << Number << std::endl;
}
};
class SportCar : public Car
{
public:
SportCar(int number);
};
SportCar::SportCar(int number)
{
std::cout << "SportCar 생성자 호출 " << "Number : " << number << std::endl;
}
디폴트 생성자를 추가하여 에러를 없앴다.

상속을 하면 무엇이 좋을까?
수 많은 데이터를 처리할 때 각각의 변수가 모두 다른 형태이면 묶어서 처리하기가 힘들다.
위 예제로 예를 들어 Sport Car 클래스 뿐만 아니라 PickUpTruck, Sedan, SUV, Bus 등등 무수히 많은 종류가 생겼을 때 각각의 클래스를 배열로 따로 지정해야 한다.
그러나 Car를 상속받아 만들면 Car 클래스에 저장이 가능해진다.
class Car
{
private:
int lotNumber;
public:
Car() : lotNumber(0) { std::cout << "Car 디폴트 생성자 호출" << std::endl; }
Car(int Number) : lotNumber(0)
{
std::cout << "Car 생성자 호출" << "Number : " << Number << std::endl;
}
};
class SportCar : public Car
{
public:
SportCar(int number);
};
class SUV : public Car
{
public:
SUV(int number);
};
class Bus : public Car
{
public:
Bus(int number);
};
SportCar::SportCar(int number)
{
std::cout << "SportCar 생성자 호출 " << "Number : " << number << std::endl;
}
SUV::SUV(int number)
{
std::cout << "SUV 생성자 호출 " << "Number : " << number << std::endl;
}
Bus::Bus(int number)
{
std::cout << "BUS 생성자 호출 " << "Number : " << number << std::endl;
}
int main()
{
// 자식클래스의 생성자 호출
Car* pArrMyCars[10] = { 0, };
pArrMyCars[0] = new SUV(0);
pArrMyCars[1] = new Bus(1);
pArrMyCars[2] = new SportCar(2);
pArrMyCars[3] = new Car(3);
for (int i = 0; i < 10; i++)
{
if (pArrMyCars[i] == NULL)
continue;
delete pArrMyCars[i];
}
}
Car* 배열 안에 Car를 상속받아 만든 클래스들을 모두 넣을 수 있다.
[C] while문 안에서 scanf 받기 (0) | 2022.01.13 |
---|---|
[C++] 가상 함수 (Virtual Function) (0) | 2022.01.08 |
[C++] 스마트 포인터 (0) | 2022.01.08 |
[C++] 클래스 생성자와 소멸자 (0) | 2022.01.01 |
[C++] 오버로딩과 오버라이딩 차이 (0) | 2022.01.01 |