프로그래밍/C++

가상함수, 순수가상함수, 추상클래스

swedu 2023. 2. 24. 11:39
728x90
반응형

2023.02.24  최초 작성

 

 

 

가상함수 : 파생 클래스에서 재정의할 것을 기대하는 함수이다.

 

모양

virtual function(){

 

}

 

순수 가상함수 : 구현 없이 선언만 있는 함수이다.

 

모양

virtual void function() = 0;

 

 

추상 클래스 : 순수 가상함수를 가지고 있는 클래스로 객체를 만들지 못하여 상속으로만 사용할 수 있다.

 

 

static_cast : compile 타임에 형 변환 타입 오류를 잡아준다.

부모 클래스에서 자식 클래스로 downcast 할 때는 unsafe 하게 동작할 수 있다.

 

사용법

static_cast<바꾸려고 하는 타입>(대상);

 

 

 

dynamic_cast : run 타임에 형 변환 타입 오류를 잡아준다.

static_cast에 비해 속도가 느리다.

부모 클래스에서 자식 클래스로 downcast 할 때는 safe 하게 동작할 수 있다.

 

사용법

dynamic_cast<바꾸려고 하는 타입>(대상);

 

 

#include <iostream>
using namespace std;
class Animal {
public:
	Animal() {
		cout << "Animal 클래스 생성자 실행" << endl;
	}
	virtual void talk() = 0;
	virtual void eat() {
		cout << "사료를 먹는다." << endl;
	}
};
class Dog : public Animal{
public:
	Dog() :Animal(){
		cout << "Dog 클래스 생성자 실행" << endl;
	}
	void talk() override{
		cout << "멍멍!" << endl;
	}
};
class Cat : public Animal {
public:
	Cat() :Animal() {
		cout << "Cat 클래스 생성자 실행" << endl;
	}
	void talk() override {
		cout << "야옹~" << endl;
	}
	void eat() override {
		cout << "고양이 사료를 먹는다." << endl;
	}
};
int main() {
	Dog* d = new Dog();
	Cat* c = new Cat();
	Animal* a[] = {d, c};  // 묵시적 형변환
	for (int i = 0; i < 2; i++) {
		a[i]->talk();
		a[i]->eat();
	}
	for (int i = 0; i < 2; i++) {
		delete a[i];
	}
	return EXIT_SUCCESS;
}

[실행 결과]

Animal 클래스 생성자 실행

Dog 클래스 생성자 실행

Animal 클래스 생성자 실행

Cat 클래스 생성자 실행

멍멍!

사료를 먹는다.

야옹~

고양이 사료를 먹는다.

 

 

#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Animal {
protected:
	string name;
public:
	Animal(string name):name(name) {
		cout << "Animal 클래스 생성자 실행 : " << name << endl;
	}
	virtual void talk() {
		cout << name << " : 말한다." << endl;
	}
	virtual void eat() {
		cout << name << "가 먹이를 먹는다." << endl;
	}
};
class Dog : public Animal {
public:
	Dog(string name) :Animal(name) {
		cout << "Dog 클래스 생성자 실행 : " << name << endl;
	}
	void talk() override {
		cout << name << " : 멍멍!" << endl;
	}
	void dogMethod() {
		cout << "나는 강아지이다." << endl;
	}
};
class Cat : public Animal {
public:
	Cat(string name) :Animal(name) {
		cout << "Cat 클래스 생성자 실행 : " << name << endl;
	}
	void talk() override {
		cout << name << " : 야옹~" << endl;
	}
	void eat() override {
		cout << name << "가 간식을 먹는다." << endl;
	}
	void catMethod() {
		cout << "나는 고양이이다." << endl;
	}
};
int main() {
	vector<Animal*> v;
	v.push_back(new Cat("나비"));
	v.push_back(new Dog("멍멍이"));
	v.push_back(new Animal("토끼"));
	Cat* cat=nullptr;
	Dog* dog=nullptr;

	cout << endl;
	cout << "-------명시적형변환----------" << endl;
	for (int i = 0; i < v.size(); i++) {
		cout << "-----------------------" << endl;
		cat = (Cat*)v[i];
		cat->talk();
		cat->eat();
		cat->catMethod();
		dog = (Dog*)v[i];
		dog->talk();
		dog->eat();
		dog->dogMethod();
	}
	cout << endl;
	cout << "------static_cast--------" << endl;
	for (int i = 0; i < v.size(); i++) {
		cout << "-----------------------" << endl;
		cat = static_cast<Cat*>(v[i]);
		cat->talk();
		cat->eat();
		cat->catMethod();
		dog = static_cast<Dog*>(v[i]);
		dog->talk();
		dog->eat();
		dog->dogMethod();
	}
	cout << endl;
	cout << "-------dynamic_cast--------" << endl;
	for (int i = 0; i < v.size(); i++) {
		cout << "-----------------------" << endl;
		if ((cat = dynamic_cast<Cat*>(v[i])) != nullptr) {
			cat->talk();
			cat->eat();
			cat->catMethod();
		}
		else if ((dog = dynamic_cast<Dog*>(v[i])) != nullptr) {
			dog->talk();
			dog->eat();
			dog->dogMethod();
		}
		else {
			v[i]->talk();
			v[i]->eat();
		}
	}

	if(cat != nullptr)
		delete cat;
	if(dog != nullptr)
		delete dog;
	return EXIT_SUCCESS;
}

[실행 결과]

Animal 클래스 생성자 실행 : 나비

Cat 클래스 생성자 실행 : 나비

Animal 클래스 생성자 실행 : 멍멍이

Dog 클래스 생성자 실행 : 멍멍이

Animal 클래스 생성자 실행 : 토끼

 

-------명시적형변환----------

-----------------------

나비 : 야옹~

나비가 간식을 먹는다.

나는 고양이이다.

나비 : 야옹~

나비가 간식을 먹는다.

나는 강아지이다.

-----------------------

멍멍이 : 멍멍!

멍멍이가 먹이를 먹는다.

나는 고양이이다.

멍멍이 : 멍멍!

멍멍이가 먹이를 먹는다.

나는 강아지이다.

-----------------------

토끼 : 말한다.

토끼가 먹이를 먹는다.

나는 고양이이다.

토끼 : 말한다.

토끼가 먹이를 먹는다.

나는 강아지이다.

 

------static_cast--------

-----------------------

나비 : 야옹~

나비가 간식을 먹는다.

나는 고양이이다.

나비 : 야옹~

나비가 간식을 먹는다.

나는 강아지이다.

-----------------------

멍멍이 : 멍멍!

멍멍이가 먹이를 먹는다.

나는 고양이이다.

멍멍이 : 멍멍!

멍멍이가 먹이를 먹는다.

나는 강아지이다.

-----------------------

토끼 : 말한다.

토끼가 먹이를 먹는다.

나는 고양이이다.

토끼 : 말한다.

토끼가 먹이를 먹는다.

나는 강아지이다.

 

-------dynamic_cast--------

-----------------------

나비 : 야옹~

나비가 간식을 먹는다.

나는 고양이이다.

-----------------------

멍멍이 : 멍멍!

멍멍이가 먹이를 먹는다.

나는 강아지이다.

-----------------------

토끼 : 말한다.

토끼가 먹이를 먹는다.

 

 

728x90
반응형

 

728x90
반응형

'프로그래밍 > C++' 카테고리의 다른 글

list  (0) 2023.02.27
vector  (0) 2023.02.27
상속  (0) 2023.02.23
연산자 중복  (0) 2023.02.21
프랜드  (0) 2023.02.21