nakka soft world !
가상함수와 다형성 본문
Upcasting
class Animal
{
public:
int age;
string name;
};
class Dog : public Animal
{
public:
int color
};
int main()
{
double d = 3.4;
int* pn = &d; // error. void ptr은 가능
Dog dogAnimal*p = &dog; // OK. 기반 클래스 포인터에 파생클래스 주소를 가르킬수 있다.
// upcasting
p->age = 2;
p->name = "kim";
p->color = 2; // error
// 기반 클래스 포인터로는 기반클래스 멤버만 접근 할수 있다.
Dog pDog = static_casting<Dog*>(p);
pDog->color = 2; // ok
}
Upcasting 활용
class Animal
{
public:
int age;
};
class Dog : public Animal{};
class Cat : public Animal{};
void HappyNewYear(Dog* p)
{
++(p->age);
}
int main()
{
Dog d;
HappyNewYear(&d);
Cat c;
HappyNewYear(&d);
}
아래 처럼 수정
class Animal
{
public:
int age;
};
class Dog : public Animal{};
class Cat : public Animal{};
void HappyNewYear(Animal* p) // 모든 동물의 공통의 특징을 처리 하는 함수
{
++(p->age);
}
int main()
{
Dog d;
HappyNewYear(&d);
Cat c;
HappyNewYear(&d);
}
class Animal
{
public:
int age;
};
class Dog : public Animal{};
class Cat : public Animal{};
int main()
{
vector<Animal*> v1; // 모든 동물을 보관하는 컨테이너
}
함수 오버라이드 (function override)
- 함수 재정의
class Animal
{
public:
void Cry() { cout << "Animal Cry" << endl; } // 1
};
public Dog : publoc Animal
{
public:
// function override
void Cry() { cout << "Dont Cry" << endl; } // 2
};
int main()
{
Animal a;
a.Cry(); // 1
Dog d;
d.Cry(); // 2
}
가상함수 (virtual function)
class Animal
{
public:
void Cry() { cout << "Animal Cry" << endl; } // 1
// 가상함수. 파생 Class가 재정의 할 것 같으면 virtual로 작성
virtual void Cry2() { cout << "Animal Cry 2" << endl; } // 3
};
public Dog : publoc Animal
{
public:
// function override
void Cry() { cout << "Dont Cry" << endl; } // 2
virtual void Cry2() { cout << "Dont Cry 2" << endl; } // 4
};
int main()
{
Animal a;
a.Cry(); // 1
Dog d;
d.Cry(); // 2
Animal* p = &d;
p-Cry(); // C++ : Animal, java : Dog
Animal* p = &d;
p-Cry2(); // Dog
}
가상함수 주의사항
1. 문법 정리
class Animal
{
public:
virtual void Cry() { cout << "Animal Cry" << endl; }
virtual void Cry2() { cout << "Animal Cry2" << endl; }
};
public Dog : publoc Animal
{
public:
void Cry() { cout << "Dont Cry" << endl; } // virtual이 없어도 가상함수
virtual void Cry2();
};
// 구현에는 virtua을 표기 하지 않는다.
void Dog::Cry()
{
cout << "Dont Cry 2" << endl;
}
int main()
{
Animal* p = new Dog;
p->Cry();
}
onverride - C++11
lass Animal
{
public:
virtual void Cry() { cout << "Animal Cry" << endl; }
virtual void Cry3() { cout << "Animal Cry" << endl; }
};
public Dog : publoc Animal
{
public:
virtual void Cry2() { cout << "Dont Cry" << endl; } // 새로운 함수로 정의됨
// C++11 override 문법
virtual void Cry3() override { cout << "Dont Cry" << endl; } // override는 과거 에는 없던 문법. C++11이상 이면 최대한 붙여라.
};
int main()
{
Animal* p = new Dog;
p->Cry();
}
기반 클래스 포인터로 비가상 함수를 호출하면 항상 기반 클래스의 함수가 호출됩니다.
파생 클래스가 호출되게 하려면 가상 함수를 사용해야 합니다.
'프로그래밍언어 > C++' 카테고리의 다른 글
가상 소멸자 ( virtual destructor ) (0) | 2017.03.27 |
---|---|
객체 지향 디자인 (0) | 2017.03.27 |
상속의 개념 (0) | 2017.03.25 |
STL 설계 철학 (0) | 2017.03.19 |
알고리즘의 정책 변경 (0) | 2017.03.19 |