TIL/TIS 211202

gyeon·2021년 12월 2일
0

TIL/TIS

목록 보기
12/14

가상함수란

virtual키워드가 붙은 맴버함수는 기반 클래스에서 선언되서, 파생클래스에 의해 재정의된다.
이러한 virtual키워드를 사용하면 실행시간중에 다형성을 구현할 수 있다.

가상함수 사용시 주의할점

  1. public 접근지정자여야 한다.
  2. ststic일수 없다.
    -> 비정적 멤버 함수만 가상일 수 있습니다.C/C++(314)
  3. 실행시간 다형성을 얻기 위해 기반 클래스의 포인터/참조를 통해 접근해야한다.
    -> base *p_base = &derived;
  4. 가상함수의 프로토타입(반환형,매개변수형)은 파생클래스에서도 동일해야한다.
  5. (함수는 아니지만) 가상 소멸자를 가질수 있다(생성자는 불가능).
#include <iostream>

class base {
	public :
		virtual void base_func() {
			std::cout << "base" << std::endl;
		}
};

class derived : public base {
	public :
		void base_func() {
			std::cout << "derived" << std::endl;
		}
};


int main() {
	base bs;
	derived dr;
	
	bs.base_func();
	dr.base_func();

	base *p_bs1 = &bs;
	base *p_bs2 = &dr;
	std::cout << "base포인터에 base의 주소\n> ";
	p_bs1->base_func();	//> base
	std::cout << "base포인터에 derived의 주소\n> ";
	p_bs2->base_func(); //> derived
}

-> 런타임에 base_func()가 기반 클래스의 로직을 실행할지, 파생클래스의 로직을 실행할지 정해진다.

override 키워드

위처럼 파생 클래스에서 메소드를 잘 사용하면 문제가 안되지만, 미묘한 차이로 잘못사용해서 override되지 않고, 파생클래스의 새로운 맴버함수로서 만들어지는 경우가 있다.
ex) derived의 func1은 상수함수라서 override로 취급되지 않는다.

class Base {
	...
    public :
    virtual void func1(int a) {
    	...
    }
};
...
class derived : public Base {
	...
    public :
    virtual void func1(int a) const {
    	...
    }
};

이때, 파생클래스의 func1에 override키워드를 붙여주면, override하는 func1이 아니면 컴파일 에러가 발생한다.

#include <iostream>
class Base {
	public :
	virtual void func1(int a) {
		std::cout << a << std::endl;
	}
};

class derived : public Base {
	public :
	//void func1(int a) const override {
	//> 'override'로 선언된 멤버 함수는 기본 클래스 멤버를 재정의하지 않습니다.C/C++(1455)
	void func1(int a) override {
		std::cout << a + 42 << std::endl;
	}
};

int main() {
	derived dr;
	Base *p_bs = &dr;

	dr.func1(3);	// 45
	p_bs->func1(3);	// 45 -> 기반클래스의 포인터지만, override됨.
}

override키워드는 vertual키워드와 꼭 같이쓸 필요는 없다. 그냥 override해야하는 맴버함수에 넣어주면 된다.

참고한 블로그

profile
백엔드와 서버 in 42Seoul

0개의 댓글