C++ 다형성(virtual)

Joosi_Cool·2022년 11월 9일
3

C++

목록 보기
20/20
post-thumbnail

다형성이란?

다형성이란, 아래 예시를 보자.
부모 클래스와 자식 클래스가 있을때, 같은 형태의 함수가 있다고 가정하자.
또한 부모 포인터가 자식 객체를 가리키고 있다.
그렇다면 우리는 당연히 포인터로 함수를 선언하면, 자식 객체의 함수가 선언되어야 된다고 생각할 것이다. 하지만 그렇지 않다. 이는 정적 바인딩 때문이다.

예시코드

class Base {
public:
	void Talk() {
		cout << "Base" << endl;
	}
};

class Derived :public Base {
public:
	void Talk() {
		cout << "Derived" << endl;
	}

};



int main() {

	Base* a = new Derived;
	a->Talk();
	delete a;

	return 0;
}

정적바인딩 vs 동적바인딩

  • 정적바인딩: 컴파일을 진행할 때, 어떤 함수가 호출될지 정해지는 것이다.

  • 동적바인딩: 컴파일 때, 어떤 함수가 호출될지 정하는 것이 아니라, 런타임 시에 정해지는 것이다.

정적 바인딩 때문에 포인터 자료형이 부모 클래스 였을때부터 정해져 있는 것이다. 이를 해결하는 방법이 없을까? 이때 등장하는 것이 동적바인딩(virtual)이다.

virtual이란?

이를 함수 앞에 붙이면 동적바인딩을 실행한다. 동적 바인딩이란, 런타임 시에 정해지는 것으로, 실행될 함수를 미리 정해놓지 않는다. 때문에 자식 객체로 연결되있던 부모의 포인터에서 함수를 실행하면 자식의 함수가 실행되게 된다.

예시코드

아래 예시코드를 보자.

class Base {
public:
	virtual void Talk() {
		cout << "Base" << endl;
	}
};

class Derived :public Base {
public:
	void Talk() {
		cout << "Derived" << endl;
	}

};



int main() {

	Base* a = new Derived;
	a->Talk();
	delete a;
    
	return 0;
}

소멸자(virtual)

부모, 자식 사이에 있어서, 소멸자는 메모리 면에서 중요하다고 볼 수 있다. 만약에 위에 코드처럼 작성시에 메모리 누수가 발생할 수 있다.


포인터로 연결되어있던 자식 객체가 있을 것이다. 이때 부모 포인터를 소멸자를 통해 없앤다면, 자식 객체들은 어떤 포인터도 연결되어있지 않고 삭제도 안된 메모리 누수가 발생하는 것이다.
따라서 아래와 같이 부모 클래스에서 소멸자 앞에 virtual를 붙어줘야 한다. 그래야 자식 객체를 소멸시킬 수 있다.

예시코드

class Base {
public:
	virtual ~Base() {
		cout << "Base삭제" << endl;
	}
	void Talk() {
		cout << "Base" << endl;
	}


};

class Derived :public Base {
public:
	~Derived() {
		cout << "Derived삭제" << endl;
	}
	void Talk() {
		cout << "Derived" << endl;
	}

};



int main() {

	Base* a = new Derived;
	
	delete a;


	return 0;
}

profile
집돌이 FE개발자의 노트

1개의 댓글

comment-user-thumbnail
2024년 4월 13일

👍

답글 달기