C++ 상속 - 가상 함수

진경천·2023년 10월 21일
0

C++

목록 보기
53/90

가상 함수 virual

가상 함수는 파생 클래스에서 재정의할 것으로 기대하는멤버 함수를 의미
자신을 호출하는 객체의 동적 타입에 따라 실제 호출할 함수가 결정

#include <iostream>

using namespace std;

class Base {
public:
	virtual void func() {
		cout << "Base" << endl;
	}
	// virtual을 붙인 가상함수로 오버라이딩을 가능케함
};

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

void foo(Base& base) {
	base.func();
}

int main() {
	Base b;
	Derived d;

	b.func();
	d.func();

	Base& b0 = d;
	b0.func();

	Base* b1 = &d;
	b1->func();

	foo(d);
}
  • 실행 결과

    virtual로 함수를 선언했을 때
      Base
      Derived
      Derived
      Derived
      Derived

    virtual로 함수를 선언안했을 때
      Base
      Derived
      Base
      Base
      Base

#include <iostream>

using namespace std;

class Base {
public:
	virtual void func() {
		cout << "Base" << endl;
	}
	// virtual을 붙인 가상함수로 오버라이딩을 가능케함
};

class Derived : public Base {
public:
	void func() override {
		cout << "Derived" << endl;
	}
	// 부모가 virtual 선언시 자식 클래스도 암시적으로 virtual 선언
	// 함수명 오타 방지 등의 실수를 예방하기 위해 override를 붙임.
};

class Derived1 : public Derived {
public:
	void func() {
		cout << "Derived1" << endl;
	}
};

void foo(Base& base) {
	base.func();
}

int main() {
	Derived1 d1;
	foo(d1);
}
  • 실행 결과

    Derived1
    virtual 함수로 인해 부모가 아닌 자식클래스의 함수를 호출함

#include <iostream>

using namespace std;

class Character {
private:
	int _health;
	int _power;

public:
	Character(int health, int power) : _health(health), _power(power) {

	}

	virtual void damaged(int power) {
		_health -= power;
	}

	void attack(Character& target) const {
		target.damaged(_power);
	}
};

class Player : public Character {
public:
	using Character::Character;	// Character 생성자 이용

	void damaged(int power) override {
		Character::damaged(power);
		cout << "끼요옷" << endl;
	}
};

class Monster : public Character {
public:
	using Character::Character;

	void damaged(int power) override {
		Character::damaged(power);
		cout << "키에엑" << endl;
	}
};
int main() {
	Player p(200, 100);
	Monster m(100, 50);

	p.attack(m);
	m.attack(p);
}
  • 실행결과

    키에엑
    끼요옷

#include <iostream>

using namespace std;

class Character {
public:
	virtual ~Character() {
		cout << "~Character" << endl;
	}

	virtual void func() {
		cout << "Character func" << endl;
	}

};

class Player : public Character {
public:
	~Player() {
		cout << "~Player" << endl;
	}

	void func() {
		cout << "Player func" << endl;
	}


};

int main() {
	Character* ch = new Player;
	ch->func();
	delete ch;

}

// virtual을 붙이지 않으면 ch는 생성자의 타입만으로 함수 호출을 결정하지만
// virtual을 붙이게 되면 ch가 가리키는 타입을 식별하여 함수를 호출한다.
// 그러므로 소멸자는 항상 virtual을 붙여아한다.
  • 실행 결과

    Player func
    ~Player
    ~Character

profile
어중이떠중이

0개의 댓글