nakka soft world !

가상함수와 다형성 본문

프로그래밍언어/C++

가상함수와 다형성

nakka 2017. 3. 27. 15:11
728x90

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();

}



기반 클래스 포인터로 비가상 함수를 호출하면 항상 기반 클래스의 함수가 호출됩니다.

파생 클래스가 호출되게 하려면 가상 함수를 사용해야 합니다.

728x90

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

가상 소멸자 ( virtual destructor )  (0) 2017.03.27
객체 지향 디자인  (0) 2017.03.27
상속의 개념  (0) 2017.03.25
STL 설계 철학  (0) 2017.03.19
알고리즘의 정책 변경  (0) 2017.03.19
Comments