본문 바로가기
언어 공부/C++

다형성(Polymorphism)

by 세희홍 2022. 6. 27.

다형성

같은 이름을 갖는 여러 형태의 함수를 클래스별로 만들 수 있게 해주는 기능

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

댓글