1. C++ 가상 함수(Virtual Function)

1) 가상 함수(Virtual Function)란,

2) 가상 함수 선언 규칙

3) Ex.1

#include <iostream>
 
using namespace std;
 
class parent {
public :
    virtual void v_print() {
        cout << "parent" << "\\n";
    }
    void print() {
        cout << "parent" << "\\n";
    }
};
 
class child : public parent {
public :
    void v_print() {
        cout << "child" << "\\n";
    }
    void print() {
        cout << "child" << "\\n";
    }
};
 
int main() {
	  parent* p; // parent 클래스를 가리키는 포인터 p 선언
    child c; // child 클래스의 객체 c 선언
    p = &c; // 포인터 p는 c 객체를 가리킴. 
 
		// 몸체는 parent 클래스지만 실제 객체는 child 클래스이다.

    p->v_print(); // 포인터 p를 이용해 가상 함수 v_print() 호출 
    p->print(); // 포인터 p를 이용해 오버라이딩 된 함수
								// print() 호출
 
    return 0;
}
/* 실행 결과
	child
	
	parent
*/

/*
v_print() 함수는 가상 키워드로 선언되어 가상 함수가 되었으며
가상 함수는 실행시간(런타임)에 그 값이 결정됩니다. 
(후기 바인딩이라고도 합니다.)

포인터 p에는 child 클래스의 객체가 들어가 있고 
**포인터가 가리키는 위치에 따라 child 클래스의
v_print() 함수가 호출**되었으며
일반 함수인 print()는 컴파일 시간에 이미 결정되기 때문에 
31번째 줄에 p에서 print() 함수를 호출할 때
parent 클래스의 print() 함수가 호출되는것으로 
결정이 끝나버린 상태입니다.

따라서 parent 클래스의 print() 함수가 호출되게 됩니다.

4) Ex.2

#include <iostream>
 
using namespace std;
 
class parent {
public :
    void print1() { // 일반 함수 print1()
        cout << "parent print1" << "\\n";
    }
    virtual void print2() { // 가상 함수 print2()
        cout << "parent print2" << "\\n";
    }
    virtual void print3() { // 가상 함수 print3()
        cout << "parent print3" << "\\n";
    }
};
 
class child : public parent {
public :
    void print2() { // 일반 함수 print2()
        cout << "child print2" << "\\n";
    }
    void print3(int x) { // 오바라이딩 된 print3(int x)
        cout << "child print3" << "\\n";
    }
};
 
int main() {
    parent* p;
    child c;
    p = &c;
 
    p->print1();
    p->print2();
    p->print3();    
 
    return 0;
}

/* 실행 결과
parent print1

child print2

parent print3
*/

/* 
print1() 함수는 일반 함수이기 때문에 컴파일 시간에 결정이 나고 
parent 클래스의 print1() 함수가 호출됩니다.

print2() 함수는 가상 함수이기 때문에 실행 시간에 결정이 됩니다. 
parent 클래스지만 가리키고있는 객체가 child 클래스이기 때문에
child 클래스의 print2() 함수가 호출되게 됩니다.

print3() 함수는 가상 함수이지만 child 클래스에서는 
매개변수가 없는 함수를 호출했기 때문에 
부모 클래스인 parent 클래스의 print3() 함수가 호출되게 된 것입니다.
*/