// Child클래스
void SetChild(int _child) { m_Child = _child; }
Parent* pParent = nullptr;
Child c5;
c5.SetChild(10);
pParent = &c5;
Child* pChild = &c5;
pChild->SetChild(10);
부모 클래스 포인터 타입으로 자식 클래스 객체의 주소를 가리킨 경우
가상함수는 테이블에 등록된 함수를 호출하기 떄문에, 각 클래스에서 오버라이딩한 원래 버전을 사용할수 있지만
순수하게 자식 클래스부터 구현된 함수는 부모 클래스 포인터로 알 수 가 없다.
((Child*)pParent)->m_Child = 10;
Child* pChild = dynamic_cast<Child*>(pParent);
if (pChild != nullptr)
{
pChild->SetChild(10);
}
dynamic_cast
가 RTTI다.#include <typeinfo>
const type_info& info = typeid(Parent);
unsigned __int64 id = info.hash_code();
const char* pClassName = info.name();
상속
상속을 남발하다보면 클래스 종류와 갯수가 많아지고 클래스에서 만든 객체들이 존재하니까 파생되서 상속이 존나 많이되고 일괄적으로 관리가 어려워진다.
다형성
그렇지만 기능을 접근하는데 문제가 발생 부모포인터로 접근하면 부모쪽만 접근해서 자식쪽에 오버라이딩한게 접근이 안된다.
virtual (가상함수)
자식 클래스에서부터 추가된 함수에 대한 접근을 할때 문제 발생.
다운 캐스팅(강제 캐스팅, dynamic_cast)
class Animal
{
public:
// 1
virtual void Move()
{
cout << "Move" << endl;
}
};
class Bird
: public Animal
{
// 2
void Move()
{
cout << "Fly" << endl;
}
};
// 3
class Eagle
: public Bird
{
// 3
// void Move()
//{
// cout << "Fly" << endl;
//}
};
Animal animal;
Bird bird;
Eagle eagle;
// 애니멀 클래스에 순수 가상 함수 만듬.
virtual void Eat() = 0;
인터페이스
를 제시한다 고 한다.// Bird 클래스에 구현되어 있다.
void Eat()
{
cout << "pack" << endl;
}
// main.24에 있는 Child클래스 내부
public:
void SetChild(int _child) { m_Child = _child; }
void OutputMyData()
{
cout << "Child" << endl;
cout << "m_Parent : " << m_Parent << endl;
cout << "m_Child : " << m_Child << endl;
}
void VirtualFunc()
{
}
virtual void OutputMyData()
{
cout << "Child" << endl;
cout << "m_Parent : " << m_Parent << endl;
cout << "m_Child : " << m_Child << endl;
}
virtual void VirtualFunc()
{
}
virtual void Test()
{
}
// 1
virtual void Test() //override
{
}
// 2
virtual void OutputMyData() override
{
cout << "Child" << endl;
cout << "m_Parent : " << m_Parent << endl;
cout << "m_Child : " << m_Child << endl;
}
// 3
virtual void VirtualFunc() override
{
}
Child* pChild = new Child;
delete pChild;
Parent* pParent = new Child;
delete pParent;
virtual ~Parent()
{
}
상속 과정에서 부모 클래스의 가상함수를 오버라이딩 한 경우
가상함수를 오버라이딩 한 경우와, 새로 해당 클래스에서 구현한 가상함수 끼리 구별하기 위해
상속구조의 클래스를 동적할당하는 경우
상속구조를 설계할 때에는 최상위 부모 클래스의 소멸자에 virtual 키워드를 붙이는 것을 반드시 잊으면 안된다.
#include <iostream>
#include <typeinfo>
using std::cout;
using std::endl;
class Parent
{
public:
int m_Parent;
public:
// 가상 함수
virtual void OutputMyData()
{
cout << "Parent" << endl;
cout << "m_Parent : " << m_Parent << endl;
}
virtual void VirtualFunc()
{
}
public:
Parent() : m_Parent(0) {}
Parent(int _P) : m_Parent(_P) {}
virtual ~Parent()
{
}
};
class Child
: public Parent
{
public:
int m_Child;
public:
// Child 클래스 맴버함수
void SetChild(int _child) { m_Child = _child; }
// Child 클래스에서 추가된 가상함수
virtual void Test()
{
}
// 부모 클래스의 가상함수를 재정의 한 경우
virtual void OutputMyData() override
{
cout << "Child" << endl;
cout << "m_Parent : " << m_Parent << endl;
cout << "m_Child : " << m_Child << endl;
}
// 부모 클래스의 가상함수를 재정의 한 경우
virtual void VirtualFunc() override
{
}
public:
Child() :m_Child(0) {}
Child(int _P, int _C) : Parent(_P), m_Child(_C) {}
~Child()
{
}
};
class ChidlChild
: public Child
{
};
int main()
{
Parent parent;
Child child;
Parent* pP = &parent;
parent.OutputMyData();
pP->OutputMyData();
pP = &child;
child.OutputMyData();
pP->OutputMyData();
Child* pC = &child;
pC->OutputMyData();
Parent p1;
Parent p2;
Parent p3;
Parent p4;
Child c1;
Child c2;
Child c3;
Child c4;
Parent* pPP = &c1;
pPP->VirtualFunc();
ChidlChild cc;
pPP = &cc;
pPP->VirtualFunc();
Parent* pParent = nullptr;
Child c5;
c5.SetChild(10);
pParent = &c5;
Child* pChild = &c5;
pChild->SetChild(10);
((Child*)pParent)->SetChild(10);
{
Child* pChild = dynamic_cast<Child*>(pParent);
if (pChild != nullptr)
{
pChild->SetChild(100);
}
}
// 특정 클래스의 타입 정보를 가져오기
const type_info& info = typeid(Parent);
unsigned __int64 id = info.hash_code();
const char* pClassName = info.name();
// 동적할당 클래스
Child* pChild = new Child;
delete pChild;
Parent* pParent = new Child;
delete pParent;
return 0;
}
#include <iostream>
using std::cout;
using std::endl;
class Animal
{
public:
virtual void Eat() = 0; // 인터페이스
virtual void Move()
{
cout << "Move" << endl;
}
};
class Bird
: public Animal
{
public:
//virtual void Eat()
//{
// cout << "Pack" << endl;
//}
virtual void Move()
{
cout << "Fly" << endl;
}
};
class Eagle
: public Bird
{
private:
public:
virtual void Move()
{
cout << "Fly" << endl;
}
};
int main()
{
//Animal animal;
//Bird bird;
//Eagle eagle;
return 0;
}
1차 24.01.16
2차 24.01.17
3차 24.01.18
4차 24.01.19
5차 24.01.22