Virtual 함수란

BS_Lee·2024년 5월 2일
0

C++

목록 보기
6/15

Virtaul함수란?

  • 부모클래스에서 정의된 함수를 자식클래스가 물려받았을 때 구현이 되게끔하는 함수이다.
  • virtaul이라는 예약어를 사용하여 함수를 선언한다.
  • 자바의 추상메서드랑 비슷한 개념이다.
    • 추상메서드는 반드시 구현해야되는 의무가 있지만, c++에서는 구현을 안하게되면 부모의 것을 그대로 가져다 쓴다.
    • 자식에서는 재정의해서 사용이 가능하다 (오버라이딩)
class Parent{
	virtual void speak() {
		cout >> "hi, i am parent";
	}
};

class ChildA : public Parent {
	public:
		virtual void speak() {
			cout >> "hi, i am child";
		}
};

class ChildB : public Parent {
	// 아무것도 선언 안했을시에는 부모 것을 가져다 쓴다.
	public:
};

int main() {
	
	ChildA a;
	ChildB b;
	
	a.speak();
	b.speak();
	
	return 0;
}

// 출력 결과 >> hi, i am child
//             hi, i am parent

순수 가상함수

  • 순수 가상 함수가 선언된 클래스라면 추상클래스라고 한다.
  • 추상클래스로 선언이 되면 객체로 생성이 불가능하다.
  • 순수 가상함수로만 이루어진 클래스는 자바의 interface랑 동일한 기능을 하게된다.
// 순수 가상 함수
virtual void speak() = 0

순수 가상함수 예제코드 (에러 예제)

#include <iostream>

using namespace std;

class Base {
    public:
		    // 순수 가상 함수 선언
        virtual void test() = 0;
};

// 자식 클래스
class BaseChild : public Base {

};

int main(){
		
		//  에러 발생
    BaseChild a;
    a.test();
	
	return 0;
}

순수 가상 함수 예제코드 (성공예제)

#include <iostream>

using namespace std;

class Base {
    public:
		    // 순수 가상 함수 선언
        virtual void test() = 0;
};

// 자식 클래스
class BaseChild : public Base {
	public:
		// 순수 가상 함수 재정의
		virtual void test(){
			cout << "this is pure function";
		}
};

int main(){
		
    ****BaseChild a;
    a.test();
	
	return 0;
}

가상함수테이블(virtual table)

  • 가상함수들의 포인터들을 포함하는 테이블이다.
  • 각 클래스의 인스턴스에 대해 하나씩 생성된다.
  • 객체의 가상함수 호출 시에는 해당 함수에 대한 포인터를 테이블에서 찾아 실행시킨다.
  • c++에서는 자식은 부모를 가리킬 수 있지만 부모는 자식을 가리키지 못한다. 이럴 때 가상함수를 사용하기도 함.
#include <iostream>

class Parent {
public:
		// 가상함수 선언
    virtual void parentMethod() {
        std::cout << "Parent Method" << std::endl;
    }
};

class Child : public Parent {
public:
		// 자식 함수 선언
    void childMethod() {
        std::cout << "Child Method" << std::endl;
    }
};

int main() {
    Child child;
    // 업캐스팅
    Parent* parentPtr = &child;

    // 부모 포인터를 자식으로 캐스팅
    Child* childPtr = dynamic_cast<Child*>(parentPtr);
    
    if (childPtr) {
        // 캐스팅 성공
        childPtr->childMethod();
    } else {
        // 캐스팅 실패
        std::cout << "Failed to cast to Child" << std::endl;
    }

    return 0;
}
profile
설명이 가능할 때까지 공부하기.

0개의 댓글