반응형
#include <iostream>
using namespace std;
class A
{
public:
void print() { cout << "A" << endl; }
};
class B : public A
{
public:
void print() { cout << "B" << endl; }
};
class C : public B
{
public:
void print() { cout << "C" << endl; }
};
class D : public C
{
public:
void print() { cout << "D" << endl; }
};
int main()
{
A a;
a.print();
B b;
b.print();
C c;
c.print();
D d;
d.print();
A& ref = b;
ref.print();
return 0;
}
여기서 ref.print()를 하면 A가 나옵니다. B가 나올 것 같은데 A가 나오는 것을 볼 수 있으며 c를 넣어도, d를 넣어도 똑같이 A가 나옵니다.
Virtual 사용
#include <iostream>
using namespace std;
class A
{
public:
virtual void print() { cout << "A" << endl; }
};
class B : public A
{
public:
void print() { cout << "B" << endl; }
};
class C : public B
{
public:
void print() { cout << "C" << endl; }
};
class D : public C
{
public:
void print() { cout << "D" << endl; }
};
int main()
{
A a;
a.print();
B b;
b.print();
C c;
c.print();
D d;
d.print();
A& ref = b;
ref.print();
return 0;
}
하지만 virtual로 넣어주면 B가 나오는 것을 볼 수 있습니다. 이렇게 작동하는구나 라는 것을 알아두시면 됩니다.
class C : public B
{
public:
virtual void print() { cout << "C" << endl; }
};
class D : public C
{
public:
virtual int print() { cout << "D" << endl; return 0; }
};
이렇게 virtual 간에 타입이 다르다면 오류가 뜨는데요. return type을 바꿔주면서 오버라이딩을 할 수가 없습니다.
컴파일러가 오버라이딩을 잡아주지 못합니다. 그래서 오버로딩으로 인식을 해서 작동을 할 수 있습니다. 그렇기 때문에 예비조치를 하기 위해서 override를 넣어주면 됩니다. override라고 해준다면 컴파일러가 오버라이드 되는 것이라고 컴파일 에러를 찾아주는 것입니다.
virtual은 스택같은 방식이 아닌 virtual 테이블을 사용하기 때문에 느립니다. 그래서 빠른 처리를 할 때는 virtual function을 사용하진 않는데요. 의외로 프로그래밍 생활을 방해할 수도 있기 때문에 이런 소프트웨어 특성도 알아두셔야 합니다.
반응형
'IT 프로그래밍 > C++' 카테고리의 다른 글
[c++] 순수 가상 함수, 추상 기본 클래스, 인터페이스 클래스 (0) | 2024.05.28 |
---|---|
[C++] 가상 소멸자 (0) | 2024.05.28 |
[c++] 상속받은 함수를 오버라이딩 하기 (0) | 2024.05.27 |
[c++] 따배시 상속과 접근 지정자 (0) | 2024.05.27 |
[따배시 11.1 c++] 상속의 기본1 (0) | 2024.05.26 |