반응형
Header.h
#pragma once #includeAnimal.h#include using std::cout; using std::cin; using std::endl; using std::string;
#pragma once #include "Header.h" class Animal { protected: int speed; public: virtual void speak() = 0; virtual int walk(int here) = 0; virtual void setSpeed(int s) = 0; virtual int getSpeed() = 0; virtual void printSpeed() = 0; virtual void printName() = 0; public: //virtual Animal(); //생성자는 재정의될 수 없으니 가상함수로 만들수도 없다. Animal(); virtual ~Animal(); };Animal.cpp
#include "Animal.h" //어차피 오버라이딩 해야하는 함수이므로 이렇게 안에 내용이 있어도 의미가 없다. //순수 가상으로 정의하고 내용을 만들면? void Animal::setSpeed(int s) { speed = s; } Animal::Animal() { speed = 0; } Animal::~Animal() { }Dog.h
#pragma once #include "Animal.h" class Dog : public Animal { private: string name; public: //오버라이딩 함수 //vitual속성은 상속되므로 재정의한 가상 함수는 vitual키워드가 안 붙어있어도 가상함수이다. void speak(); int walk(int here); void setSpeed(int s); int getSpeed(); void printSpeed(); void printName(); //추가한 함수 virtual void bite(); public: Dog(); virtual ~Dog(); };Dog.cpp
#include "Dog.h" //클래스 외부에서는 virtual키워드를 쓸 수 없다. void Dog::speak() { cout << "멍멍" << endl; } int Dog::walk(int here) { return here + speed; } void Dog::setSpeed(int s) { speed = s; } int Dog::getSpeed() { return speed; } void Dog::printSpeed() { cout << speed << endl; } void Dog::printName() { cout << name << endl; } void Dog::bite() { cout << "개는 물수 있다." << endl; } Dog::Dog() { name = "개!"; speed = 3; } Dog::~Dog() { }cat.h
#pragma once #include "Animal.h" class Cat : public Animal { private: string name; public: //오버라이딩 함수 //vitual속성은 상속되므로 재정의한 가상 함수는 vitual키워드가 안 붙어있어도 가상함수이다. void speak(); int walk(int here); void setSpeed(int s); int getSpeed(); void printSpeed(); void printName(); //추가한 함수 virtual void claw(); public: Cat(); virtual ~Cat(); };Cat.cpp
#include "Cat.h" void Cat::speak() { cout << "야옹" << endl; } int Cat::walk(int here) { return here + speed; } void Cat::setSpeed(int s) { speed = s; } int Cat::getSpeed() { return speed; } void Cat::printSpeed() { cout << speed << endl; } void Cat::printName() { cout << name << endl; } void Cat::claw() { cout << "고양이는 할퀼 수 있다." << endl; } Cat::Cat() { name = "고양이!"; speed = 4; } Cat::~Cat() { }JumpingCat.h
#pragma once #include "Cat.h" class JumpingCat : public Cat { private: string name; public: //오버라이딩 함수 //부모에 vitual이 안 붙어있어도 부모의 부모에 붙은 virtual이 상속된다. void speak(); int walk(int here); void printName(); //추가한 함수 void jump(); public: JumpingCat(); virtual ~JumpingCat(); };JumpingCat.cpp
#include "JumpingCat.h" //오버라이딩 함수 void JumpingCat::speak() { cout << "grrrrrrr" << endl; } int JumpingCat::walk(int here) { //부모의 멤버 변수를 그대로 쓸 수 있다. return here + speed; } void JumpingCat::printName() { cout << name << endl; } //추가한 함수 void JumpingCat::jump() { cout << "JumpingCat은 점프도 할 수 있다!" << endl; } JumpingCat::JumpingCat() { //멤버 변수를 오버라이딩 하면 자식 클래스의 멤버 변수가 부모 클래스의 멤버 변수의 이름을 완전히 가리게된다. name = "점핑 캣!"; //부모의 멤버 변수를 새롭게 초기화해서 그대로 쓸 수 있다. speed = 5; } JumpingCat::~JumpingCat() { }main.cpp
#include "Dog.h" #include "JumpingCat.h" //매개변수를 부모클래스의 참조나 포인터로 받으면 자식 클래스를 다 받을 수 있다. void temp(Animal& ani) { ani.printSpeed(); } void temp1(Animal* ani) { ani->printSpeed(); } //추상클래스를 매개변수로 사용할 수 없다. //void temp2(Animal ani) //{ // ani.printSpeed(); //} int main() { //추상 클래스로는 객체를 만들 수 없다. //Animal ani; Animal* ani[3]; ani[0] = new Dog; ani[1] = new Cat; ani[2] = new JumpingCat; //부모 클래스의 포인터로 자식 클래스를 가리켜서 사용하기 for (int iCnt = 0; iCnt < 3; iCnt++) { ani[iCnt]->printName(); ani[iCnt]->speak(); cout << ani[iCnt]->walk(10) << endl; //참조를 받는 함수에 포인터를 쓸 수 없다. //temp(ani[iCnt]); temp1(ani[iCnt]); } //부모 클래스의 포인터로 자식 클래스의 멤버 함수를 호출할 수는 없다. //ani[0]->bite(); //ani[1]->claw(); //하향 형변환을 하면 가능하다. Dog* ani_0 = dynamic_cast(ani[0]); ani_0->bite(); Cat c; temp(c); JumpingCat jc; temp1(&jc); }
반응형