상세 컨텐츠

본문 제목

C++ 오버라이딩

C++/C++98

by deulee 2023. 8. 7. 12:05

본문

클래스가 상속을 받을 때 상속에서 제외되는 것들이 있다.

 

1. 생성자와 파괴자

2. 대입 연산자

3. 정적 멤버 변수와 정적 멤버 함수

4. 프렌드 관계 지정

 

이 멤버들이 상속에서 제외되는 이유는 부모 클래스만의 고유한 처리를 담당하기 때문이다. 이들을 제외하고는 부모 클래스의 모든 멤버가 파생 클래스로 무조건 상속된다. 원하지 않는 기능도 말이다.

 

그럼 만약 상속 받은 멤버와 똑같은 이름으로 똑같은 멤버를 다시 선언하면 어떻게 될까?

 

#include <iostream>

class Parent
{
public:
	int m;
	Parent(int _m) : m(_m)
	{}
	void func()
	{
		std::cout << "Parent Func" << std::endl;
	}
};

class Child : public Parent
{
public:
	int m;
	Child(int pm, int cm) : Parent(pm), m(cm)
	{}
	void func()
	{
		std::cout << "Child Func" << std::endl;
	}
};

int main(void)
{
	Child c(1, 2);
	std::cout << c.m << std::endl;
	c.func();
	return 0;
}

출력 결과

 

위의 코드를 보면 부모 코드와 자식 코드에 똑같은 이름을 가진 멤버 "m"과 함수 "func"이 정의되어 있다. 그리고 다시 재정의를 한 것이 보일 것이다.

 

이를 실행해본 결과 상속받은 멤버와 새로 정의한 멤버의 이름이 중복될 경우 자신의 멤버가 우선적으로 참조된다는 것을 알 수 있다. 그림으로 보면 다음과 같을 것이다.

 

 

이는 전역변수와 지역변수의 이름이 중복되었을 때와 유사한 규칙을 가지고 있으며 객체에서는 상속받은 멤버보다 자신의 멤버가 우선권을 가지게 된다.

 

이렇게 부모로부터 상속받은 멤버 함수를 다시 작성하는 것재정의라고 하며 이를 오버라이딩(Overriding)이라고 한다.

 

이것이 필요한 이유는 자식 클래스는 부모 클래스의 모든 멤버를 그대로 사용해야 할 의무가 없기 때문이다. 언제든 자신의 목적에 따라 재정의할 수 있게 된다.

 

그렇다고 자식에서 오버라이딩을 했다고 부모의 멤버를 호출하지 못하는 것은 아니다.

 

#include <iostream>

class Parent
{
public:
	int m;
	Parent(int _m) : m(_m)
	{}
	void func()
	{
		std::cout << "Parent Func" << std::endl;
	}
};

class Child : public Parent
{
public:
	int m;
	Child(int pm, int cm) : Parent(pm), m(cm)
	{}
	void func()
	{
		std::cout << "Child Func" << std::endl;
	}
	void callParentFunc()
	{
		Parent::func(); // :: 연산자를 통해 부모의 함수를 호출함
	}
};

int main(void)
{
	Child c(1, 2);

	std::cout << c.Parent::m << std::endl; // :: 연산자를 통해 부모의 멤버에 접근함
	c.callParentFunc();

	return 0;
}

 

요런식으로 해결할 수 있다!

 

출처

http://www.soen.kr/lecture/ccpp/cpplec.htm

 

C/C++ 강좌

 

www.soen.kr

 

'C++ > C++98' 카테고리의 다른 글

C++ [Has a] 관계  (0) 2023.08.07
C++ 다중 상속  (0) 2023.08.07
C++ 상속  (0) 2023.08.07
C++ 다양한 연산자 오버로딩의 예시  (0) 2023.08.05
C++ 전역 연산자 함수  (0) 2023.08.05

관련글 더보기