C++

[C/C++ 강좌] 77강. 오버라이딩과 정적 바인딩

코다람쥐 2022. 1. 19. 16:35

https://www.youtube.com/watch?v=L_fo_ZtMDVQ&list=PLlJhQXcLQBJqywc5dweQ75GBRubzPxhAk&index=82

 

1. 오버라이딩

override : 우선하다 (o)

overwrite : 덮어쓰다. (overwrite와 override를 착각하지않기)

 

override는 우선하는 것이지 덮어씌워지는게 아니므로 햇갈리면 안된다.

#include <iostream>

using namespace std;

class Base {
public:
	int a = 10;

	void Print() {
		cout << "From Base!!!" << endl;
	}
};

class Derived : public Base {
public:
	int a = 20;

	void Print() {
		cout << "From Derived!!!" << endl;
	}

private:
};

int main() {
	Base b;
	Derived d;

	cout << b.a << endl; // 10
	cout << d.a << endl; // 20
	cout << b.Base::a << endl; // 10
	cout << d.Derived::a << endl; // 20


	d.Print();
	d.Base::Print();
	d.Derived::Print();

}

자식클래스에서 오버라이딩 된 멤버변수나 메서드를 부모클래스의 멤버변수나 메서드로 접근하고 싶으면 "부모클래스명::멤버번수or메서드"와 같은 방법으로 접근이 가능하다.

 

2. 정적 바인딩

아래와 같은 코드는 자료형이 다르기 때문에 구문오류가 발생한다.

int a;
char* p = &a;

 

부모클래스의 포인터는 자식 클래스의 포인터를 가리킬 수 있다 때문에 아래와 같은 코드는 자료형이 달라도 C++에서 예외적으로 구문이 허용이 된다.

Derived d;
Base* b = &d;

 

그리고 동적할당도 아래와 같은 방법으로 가능하다.

int main() {
	Base* b = new Derived();
	b->Print();
	delete b;
}

 

그렇다면 실행결과가 궁금해진다 b->Print(); 를 통해 "From Base!!!"가 출력될 것인지 "From Derived!!!"가 출력 될 것인지 예상이 안간다.

결과는 "From Base!!!"가 출력된다. 그리고 그 이유가 중요하다.

 

만약에 Base를 상속받는 자식클래스들이 여러개이고 어떤 자식 클래스에는 Print()함수가 오버라이딩 되어 있지 않다고 가정을 해보자.
그렇게 될 경우에 어떤 경우에는 "From Base!!"가 출력되고 어떤 경우에는 "From 자식클래스명!!!"이 출력이 된다면 일관성이 떨어지게 된다. 이것은 코드의 수가 길어지면 더욱 더 햇갈리게 된다. 그래서 그냥 자료형을 바로 알 수 있는 부모클래스의 멤버가 호출된다. 그리고 어느 것을 호출할지 정하는 것을 바인딩이라고 하고 기본적으로 부모 클래스의 멤버가 호출되는 것이 정적 바인딩이라고 한다.