란?
C++ 클래스에서 virtual 키워드를 사용하는 함수
virtual 키워드를 이용하면!! 동적 바인딩이 됨.
동적 바인딩이란 ? (출처: http://itguru.tistory.com/210)
컴파일 시에 어떤 함수가 실행될 지 정해지지 않고, 런타임 시에 정해지는 일을 가리켜서 동적 바인딩(dynamic binding)이라고 부릅니다.
using namespace std;
class Parent
{
string s;
public:
Parent () : s("부모")
{
cout << "부모 클래스" << endl;
}
virtual void what() { cout << s << endl;}
};
class Child : public Parent
{
string s;
public:
Child () : s("자식"), Parent()
{
cout << "자식 클래스" << endl;
}
void what() { cout << s << endl;}
};
int main()
{
Parent p;
Child c;
Parent* p_c = &c;
Parent* p_p = &p;
cout << " == 실제 객체는 Parent == " << endl;
p_p->what();
cout << " == 실제 객체는 Child == " << endl;
p_c->what();
return 0;
}41번째 코드 p_c->what()의 출력은 "자식"이다. 이유는 동적 바인딩이 되기 때문이다. virtual 키워드를 사용하지 않았을 때는 p_c->what()은 출력은 "부모"이다. 이유는 p_c가 부모의 포인터이기 때문에 컴파일러는 '부모의 포인터네? 부모의 함수를 실행해야지.'라고 생각을 하기 때문이다. 하지만 virtual키워드를 넣으므로써 컴파일러는 한번 더 생각하게 된다. '부모의 포인터네? 어 근데.. 이게 부모의 객체가 맞을까? 아니네 자식을 출력하자'라고 생각하게 되는 것이다.
사실 클래스의 상속을 사용함으로써 중요하게 처리해야 되는 부분이 있습니다. 바로, 소멸자를 가상함수로 만들어야 된다는 점입니다.
using namespace std;
class Parent
{
public :
Parent()
{
cout << "Parent 생성자 호출" << endl;
}
~Parent()
{
cout << "Parent 소멸자 호출" << endl;
}
};
class Child : public Parent
{
public:
Child() : Parent()
{
cout << "Child 생성자 호출" << endl;
}
~Child()
{
cout << "Child 소멸자 호출" << endl;
}
};
int main()
{
cout << "--- 평범한 Child 만들었을 때 ---" << endl;
{
Child c;
}
cout << "--- Parent 포인터로 Child 가리켰을 때 ---" << endl;
{
Parent *p = new Child();
delete p;
}
}30번째 코드는 Child c;에서 부모 생성자 -> 자식 생성자 호출이 되고, }에서 지역이 끝나므로 소멸자가 호출이된다. 이때 자식 소멸자 -> 부모 소멸자 순으로 호출이된다. 근데 문제는 아래의 34번째 코드에서 발생한다. Parent *p = new Child();에서 delete p;를 호출한다면 자식의 소멸자가 아닌 부모의 소멸자가 호출(부모의 소멸자가 호출되기 때문에 자식의 메모리 누수가 발생한다)이 된다. 하지만 이 소멸자들을 virtual로 선언을 해주면 우리가 원하는 30번째 코드처럼의 호출이 가능해진다.
이와 같은 연유로, 상속될 여지가 있는 Base 클래스들은 (위 경우 Parent), 반드시 소멸자를 virtual 로 만들어주어야 나중에 문제가 발생할 여지가 없게 됩니다.
(출처: http://itguru.tistory.com/211 [Programming IT])
순수 가상함수함수와 추상 클래스
class Animal
{
public:
Animal() {}
virtual ~Animal() {}
virtual void speak() = 0;//순수 가상함수 (자바의 추상 메소드)
};추상 클래스란? 순수 가상함수를 적어도 하나 이상 포함하고 있는 함수를 추상클래스라고 함.(자바랑 같음, 여기서 순수 가상함수란? 자바의 추상 메소드와 같음, 즉 구현이 안되어있어야함. cpp에서는 virtual void 함수명 = 0;으로 순수가상함수임을 알림)
'언어, git > C++' 카테고리의 다른 글
Const(상수) 선언 위치 (0) | 2019.03.26 |
---|---|
복사 생성자 (0) | 2017.11.19 |