프로그래밍 언어/cpp
[C++] 클래스 상속
TyT.
2023. 2. 12. 22:45
반응형
상속
앞선 포스팅에서도 언급한적이 있지만, 필자는 학부에서 자바를 배웠기 때문에 상속의 자세한 이론은 다루지 않을 것이다.
일단 상속을 전체적으로 다룬 예제코드다. 필자와 같이 상속에 대한 개념이 잡혀있다면 이 코드만봐도 대략적으로 이해가 될 것이다.
#include <iostream>
using namespace std;
class Parent
{
public:
int a;
float b;
public:
void func()
{
cout << "부모멤버함수" << a << endl;
}
// virtual은 자식클래스를 Parent포인터로 받아서 vFunc함수를 호출하면 오버라이딩된 함수를 호출하게 해준다.
virtual void vFunc()
{
cout << "부모버추얼멤버함수" << b << endl;
}
public:
Parent()
: a(1), b(2)
{
cout << "부모생성자" << endl;
}
~Parent()
{
cout << "부모소멸자" << endl;
}
};
// 상속문법은 : public 부모클래스
class Child : public Parent
{
private:
int a;
public:
void func()
{
cout << "자식멤버함수(오버라이딩)" << a << endl;
}
virtual void vFunc()
{
cout << "자식버추얼멤버함수" << b << endl;
}
void cFunc()
{
// 부모 함수의 a를 사용하는 방법
cout << "자식멤버함수" << Parent::a << endl;
}
public:
Child()
: a(10)
// , Parent() // 생략된 부모 생성자. 명시하지않으면 기본 생성자를 호출.
{
cout << "자식생성자" << endl;
}
~Child()
{
cout << "자식소멸자" << endl;
}
};
int main()
{
Parent parent;
Child child;
// 부모생성자
// 부모생성자
// 자식생성자
cout << 1 << endl;
parent.func();
parent.vFunc();
// 1
// 부모멤버함수1
// 부모버추얼멤버함수2
cout << endl
<< 2 << endl;
child.func();
child.vFunc();
child.cFunc();
// 2
// 자식멤버함수(오버라이딩)10
// 자식버추얼멤버함수2
// 자식멤버함수1
cout << endl
<< 3 << endl;
Parent *pPointer;
// pPointer = &parent; //당연히 문제없음
pPointer = &child; // 가능.
pPointer->func();
pPointer->vFunc();
// pPointer->cFunc(); //불가능. 포인터가 Parent타입이기 때문
// 3
// 부모멤버함수1
// 자식버추얼멤버함수2
cout << endl
<< 4 << endl;
Child *cPointer;
// cPointer = &parent; //불가능
cPointer = &child; // 당연히 가능
cPointer->func();
cPointer->vFunc();
cPointer->cFunc();
// 4
// 자식멤버함수(오버라이딩)10
// 자식버추얼멤버함수2
// 자식멤버함수1
cout << endl
<< 5 << endl;
// cPointer = (Child *)pPointer; //C스타일 강제캐스팅. 가능. 하지만 위험
cPointer = dynamic_cast<Child *>(pPointer);
if (nullptr != cPointer) // 다이나믹캐스트를 사용하면 오류검출이 가능해짐
{
cPointer->func();
cPointer->vFunc();
cPointer->cFunc();
}
// 5
// 자식멤버함수(오버라이딩)10
// 자식버추얼멤버함수2
// 자식멤버함수1
return 0;
// 자식소멸자
// 부모소멸자
// 부모소멸자
}
상속 문법
class Child : public Parent
생성자
자식 클래스가 생성자를 호출시
자식 생성자 호출->부모 생성자 호출->부모 생성자 실행 -> 자식 생성자 실행
순으로 실행된다.
이때, 부모생성자를 명시하지않으면 기본생성자를 호출한다. 만약 오버로딩한 생성자를 호출하고 싶다면 명시할 것.
소멸자
자식 클래스 소멸자를 호출시
자식 소멸자 호출->자식 소멸자 실행 -> 부모 소멸자 호출 -> 부모 소멸자 실행
순으로 실행된다.
마찬가지로 부모소멸자를 필요시 명시할것.
포인터
부모클래스의 포인터는 자식클래스의 객체 주소값을 받을 수 있다. 하지만 포인터가 부모클래스이기 때문에 부모클래스의 멤버들만 사용이 가능하다.
반대로 자식클래스의 포인터는 부모클래스의 객체 주소값을 받을 수 없다.
virtual
virtual
키워드는 부모클래스의 멤버함수에 선언시 부모클래스의 포인터가 자식클래스 객체를 받아서 멤버함수를 실행할때, 오버라이딩되어있다면 자식클래스의 멤버함수를 호출하게 해준다.
dynamic_cast
C스타일의 강제캐스팅의 역할을 안전하게 실행하게 해준다.(다운캐스팅) 사용방법은 예제 참조. 당연히 부모클래스 포인터가 자식클래스의 객체주소값을 받았을 때에만 자식클래스로 다운캐스팅이 가능하다.
반응형