다형성
같은 이름을 갖는 여러 형태의 함수를 클래스별로 만들 수 있게 해주는 기능
printArea를 Circle, Rectangle 객체에서 사용할 수 있다.
virtual function
#include <iostream>
#include <string>
using namespace std;
// 베이스 클래스의 정의
class Base
{
public:
virtual void print() const { cout << "베이스 클래스" << endl; } //virtual: 자식
};
// 파생 클래스의 정의
class Derived : public Base
{
public:
void print() const { cout << "파생 클래스" << endl; }
};
int main()
{
Base* ptr; // 베이스 클래스에 대한 포인터 생성
ptr = new Base(); // ptr 포인터로 부모(베이스) 클래스의 객체 가리키기
ptr->print();
delete ptr; // 힙 지우기
ptr = new Derived(); // ptr 포인터로 파생 클래스의 객체 가리키기(자식 클래스의 객체가 부모클래스 주소 받음)
ptr->print();
delete ptr;
return 0;
}
print 멤버함수 앞에 virtual 키워드가 없으면
베이스 클래스
베이스 클래스
로 출력된다.
ptr = new Derived(); 에서
ptr 포인터로 파생 클래스의 객체 가리키기 때문에 자식 클래스의 객체가 부모클래스 주소 받는다.
부모 클래스 포인터이므로 ptr->print()가 부모것이 실행된다.
virtual void print(); 로 선언을 하면 어떤 객체의 print()를 실행할지(부모 or 자식) 선택을 할 수 있다.
virtual 생성자
virtual이 해당되지 않는다. 생성자는 클래스와 이름이 같으니까 부모와 자식이 같을 수가 없다.
virtual 소멸자
메모리 누수를 피하기 위해 virtual로 만드는 게 필요하다.
- virtual 사용: 프로그램을 종료하면 각각의 소멸자가 호출이 되고, 메모리 누수가 발생하지 않는다.
- virtual 사용 안함: 부모 클래스의 포인터를 받아서 같은 포인터로 자식 클래스를 가리킨다. 힙에 있는 거를 지울 수 없어서 메모리 누수현상 발생. 부모 클래스 소멸자에 virtual을 넣으면 부모클래스의 포인터라도 자식클래스의 객체를 가리키므로 자식클래스를 제거할 수 있다.
class Person
{
private:
string name;
public:
Person(string name);
virtual ~Person();
virtual void print() const;
};
동적 자료형 변환
- 업캐스트
Person* ptr1 = new Student
베이스 클래스에 대한 포인터에 파생 클래의 객체 넣기
- 다운 캐스트
Student* ptr2 = dynamic_cast<Student*>(ptr1)
파생 클래스에 대한 포인터에 베이스 클래스의 객체를 넣는 것. Student 클래스가 Person 클래스의 파생 클래스일 때만 가능
'언어 공부 > C++' 카테고리의 다른 글
공용체(Union) (0) | 2022.06.29 |
---|---|
구조체(struct) (0) | 2022.06.29 |
클래스 간의 관계: 의존 (0) | 2022.06.26 |
클래스 간의 관계: 연관 (0) | 2022.06.26 |
클래스 간의 관계: 상속 - 3(person-student-employee) (0) | 2022.06.26 |
댓글