일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- BST
- 연결 리스트
- 오버로딩
- 선물
- 템플릿 함수화
- Basic
- 바이낸스
- Tree
- 알고리즘
- mutable
- 기초
- linked list
- #선물 #비트코인#알트코인#매매#코인#마진
- C++
- 이진 탐색 트리
- SCM
- 트리
- Windows
- 전위
- 후위
- 비트코인
- 문자열
- Data Structure
- 자료구조
- Python
- array
- 숫자
- trading view
- 순회
- template
Archives
- Today
- Total
Project Hub
11. virtual 함수와 다형성 본문
728x90
반응형
이전 글
2022.12.21 - [C++/c++ basic] - 10. 업 캐스팅 & 다운 캐스팅
10. 업 캐스팅 & 다운 캐스팅
이전 글 2022.12.21 - [C++/c++ basic] - 9. 전위/후위 증감 연산자 오버로딩 & 첨자 연산자 오버로딩 9. 전위/후위 증감 연산자 오버로딩 & 첨자 연산자 오버로딩 이전 글 2022.12.21 - [C++/c++ basic] - 8. 입출력
projecthub.tistory.com
다형성
하나의 메소드를 호출했음에도 불구하고 여러가지 다른 작업들을 하는 것.
virtual 키워드
컴파일 시에 어떤 함수가 실행될 지 정해지지 않고 런타임 시 정해지는 동적 바인딩을 수행한다.
예제 코드는 다음과 같다.
#include <iostream>
class CBase
{
public:
CBase() { std::cout << "=== 기반 클래스 ===" << std::endl; }
virtual void what() { std::cout << "기반 클래스의 what()" << std::endl; }
};
class CDerived : public CBase
{
public:
CDerived() { std::cout << "=== 파생 클래스 ===" << std::endl; }
void what() { std::cout << "파생 클래스의 what()" << std::endl; }
};
int main()
{
CBase b;
CDerived d;
CBase* pb = &d;
CBase* pc = &b;
std::cout << "=== 실제 객체는 CBase ===" << std::endl;
pc->what();
std::cout << "=== 실제 객체는 CDerived ===" << std::endl;
pb->what();
return 0;
}
// 출력
=== 기반 클래스 ===
=== 기반 클래스 ===
=== 파생 클래스 ===
=== 실제 객체는 CBase ===
기반 클래스의 what()
=== 실제 객체는 CDerived ===
파생 클래스의 what()
override 키워드
파생 클래스에서 기반 클래스의 가상 함수를 오버라이드 하는 경우, override 키워드를 통해 명시적으로 표시 가능.
아래의 경우, override 가 정상적으로 되지 않는다.
이유는, const 키워드로 상수 함수로 선언되었기 때문이다.
#include <iostream>
class CBase
{
public:
CBase() { std::cout << "=== 기반 클래스 ===" << std::endl; }
virtual void what() { std::cout << "기반 클래스의 what()" << std::endl; }
};
class CDerived : public CBase
{
public:
CDerived() { std::cout << "=== 파생 클래스 ===" << std::endl; }
void what() const { std::cout << "파생 클래스의 what()" << std::endl; } // const 로 선언됨.
};
int main()
{
CBase b;
CDerived d;
CBase* pb = &d;
CBase* pc = &b;
std::cout << "=== 실제 객체는 CBase ===" << std::endl;
pc->what();
std::cout << "=== 실제 객체는 CDerived ===" << std::endl;
pb->what();
return 0;
}
위의 문제를 해결하기 위해서는 const 키워드를 지워주면 된다.
또한 override 키워드를 입력하여 명시적으로 표시하는 것도 방법이다.
class CBase
{
public:
CBase() { std::cout << "=== 기반 클래스 ===" << std::endl; }
virtual void what() { std::cout << "기반 클래스의 what()" << std::endl; }
};
class CDerived : public CBase
{
public:
CDerived() { std::cout << "=== 파생 클래스 ===" << std::endl; }
void what() override { std::cout << "파생 클래스의 what()" << std::endl; }
};
...
...
순수 가상 함수
반드시 오버라이딩 되어야만 하는 함수.
가상 함수에 = 0; 을 붙여서 만든다.
순수 가상 함수를 최소 한개 포함하고 있는, 반드시 상속 되어야 하는 클래스를 추상 클래스 라고 한다.
#include <iostream>
class CAnimal
{
public:
CAnimal() {}
virtual ~CAnimal() {}
virtual void speak() = 0; // 순수 가상 함수
};
class CDog : public CAnimal
{
public:
CDog() : CAnimal() {}
virtual ~CDog() {}
virtual void speak() override { std::cout << "왈왈" << std::endl; }
};
class CCat : public CAnimal
{
public:
CCat() : CAnimal() {}
virtual ~CCat() {}
virtual void speak() override { std::cout << "야옹야옹" << std::endl; }
};
int main()
{
// CAnimal animal; 객체 생성은 불가하다. 순수 가상 함수가 있기 때문에 막았다.
CAnimal* dog = new CDog();
CAnimal* cat = new CCat();
dog->speak();
cat->speak(); return 0;
}
다중상속 시 주의해야 할 점
아래와 같이 상속이 이루어진다면,
B와 C 클래스가 A 클래스의 변수를 상속 받기 때문에 D 클래스에서는 A의 모든 내용이 중복되는 문제가 발생한다.
class A
{
public:
// ...
}
class B : public A
{
public:
// ...
}
class C : public A
{
public:
// ...
}
class D : public B, public C
{
public:
// ...
}
이런 중복의 문제를 해결하기 위해서는 virtual 키워드를 사용하면 된다.
class A
{
public:
// ...
}
class B : public virtual A
{
public:
// ...
}
class C : public virtual A
{
public:
// ...
}
class D : public B, public C
{
public:
// ...
}
728x90
반응형
'C++ > c++ basic' 카테고리의 다른 글
13. 파일 입출력 (1) | 2022.12.21 |
---|---|
12. 입출력 (istream, ostream) (0) | 2022.12.21 |
10. 업 캐스팅 & 다운 캐스팅 (0) | 2022.12.21 |
9. 전위/후위 증감 연산자 오버로딩 & 첨자 연산자 오버로딩 (0) | 2022.12.21 |
8. 입출력 연산자 오버로딩 (1) | 2022.12.21 |
Comments