클래스 (객체지향)

클래스 상속(inheritance) 이란?? (생성자,소멸자 접근 제어 지시자)

ShadowEye 2021. 6. 21. 15:02

 

1. 상속(inheritance) 이란?


상속의 사전적의미 및 설명은 아래링크에서 가져왔습니다.
http://tcpschool.com/cpp/cpp_inheritance_derivedClass


 

상속(inheritance)은 추상화, 캡슐화와 더불어 객체 지향 프로그래밍을 구성하는 중요한 특징 중 하나입니다.

상속은 사용자에게 높은 수준의 코드 재활용성을 제공하며, 클래스 간의 계층적 관계를 구성함으로써 다형성의 문법적 토대를 마련합니다.

 

C++에서 클래스 상속이란 기존에 정의되어 있는 클래스의 모든 멤버 변수와 멤버 함수를 물려받아, 새로운 클래스를 작성하는 것을 의미합니다.

이때 기존에 정의되어 있던 클래스를 기초 클래스(base class) 또는 부모 클래스(parent class), 상위 클래스(super class)라고도합니다.

그리고 상속을 통해 새롭게 작성되는 클래스를 파생 클래스(derived class) 또는 자식 클래스(child class), 하위 클래스(sub class)라고도 합니다.

 

이와 같은 클래스의 상속은 다음과 같은 장점을 가집니다.

 

1. 기존에 작성된 클래스를 재활용할 수 있습니다.

2. 공통적인 부분은 기초 클래스에 미리 작성하여, 파생 클래스에서 중복되는 부분을 제거할 수 있습니다.


상속은 글자 그대로 상속해주는 클래스(상위, 부모)가 가지고있는 특징(멤버변수, 함수등)을 상속받는 클래스에게 상속하므로써 상속받은 (하위, 자식) 클래스가 부모클래스의 멤버 변수와 멤버 함수를 사용할수있게 한다.

 

상속의 형태는 다음과 같다.

class Parent
{
public:
	void Print() {
		cout << "나는 부모" << endl;
	}
	int a;
	int b;
};

class Child : public Parent
{ 

	
public:
	int c;
	void AnotherPrint() { 
		cout << "나는 자식" << endl;
	}
};

int main() {
	Parent parent;
	Child child;

	child.Print(); //사용가능

	parent.AnotherPrint(); //사용불가
}

보시다시피 Child클래스은 Parent클래스의 함수인 Print()를 사용 가능하지만

Parent클래스는 Child클래스의 함수인 AnotherPrint()를 사용할수없다

이러한 상속이 특징을 이용하면 유지보수작업에 용이함과 동시에 객체 특성을 살릴수있는 다형성까지 얻을수있다.

 

2. 접근 지시 제어자 (Access Modifier)

그렇다면 부모로 상속받은것중 어떤건 사용가능하고 어떤건 사용 불가능하게 설정이 가능할까???

 

그럴때 사용하는것이 바로 접근 지시 제어자인 public protected private이다.

 

위 세가지 지시제어자는 다음과 같은 특성을 지닌다.

 

예제는 다음과 같다.

#include <iostream>
using namespace std;

class Parent {
private:
	int a;
protected:
	int b;
public:
	int c;
};

class Child : private Parent { //b,c맴버 변수는 private 맴버로 접근 범위 졻혀짐

};

class AnotherChild : protected Parent { //b,c맴버 변수는 public 맴버로 접근 범위 졻혀짐

};

class AnotherAnotherChild : public Parent { //b,c맴버 변수는 public 맴버로 접근 범위 졻혀짐

};


int main() {
	Child child;
	//a = private, b = private, c = private
	child.a; //사용불가
	child.b; //사용불가
	child.c; //사용불가

	AnotherChild anotherChild;
	//a = protected, b = protected, c = protected
	anotherChild.a;	//사용불가
	anotherChild.b;	//사용불가
	anotherChild.c;	//사용불가

	AnotherAnotherChild anotherAnotherChild;
	//a = public, b = public, c = public
	anotherAnotherChild.a;	//사용불가
	anotherAnotherChild.b;	//사용불가
	anotherAnotherChild.c;	//사용가능
}

2.1 private 상속

Child는 Parent를 private로 상속받는다.

 

Parent의 맴버변수 b,c는 private보다 범위가 넓으므로 b,c는 private로 제한한다.

 

따라서 a,b,c 모두 접근할 수 없다.

 

2.2 protected 상속

Child는 Parent를 protected로 상속받는다. 

 

Parent의 맴버변수 c는 protected보다 범위가 넓으므로 c는 protected로 제한한다.

 

따라서 a,b,c 모두 접근할 수 없다.

 

2.3 public 상속

Child는 Parent를 public로 상속받는다.

 

따라서 a,b는 접근할 수 없지만 c는 접근할수 있다.

 

3. 클래스의 생성자, 소멸자 

3.1 생성자(Constructor)

클래스는 객체를 생성할때 항상 호출하는 함수를 생성자라고 부른다.

생성자 함수를 사용하여 맴버 변수의 초기화 메모리 할당등을 한다.

생성자를 사용할려면 반듯이 public으로 선언해야 외부에서 사용할수있지만 귀찮으면 생략하더라도 c++은 알아서 

 

기본 생성자(Default Constructor) 만들어준다. 

 

3.1.1 자식에서의 생성자

부모로부터 상속받은 자식클래스는 자기만의 생성자를 정의해야한다. (정의하지않을경우 부모클래스가 호출됨)

아래 코드는 부모클래스에서 생성자를 정의한 이유 자식클래스에서 생성자를 정의한것이다.

 

Parent::Parent(int num1, int num2) : a(num1), b(num2) { }

Child::Child(int val1, int val2) : Parent(val1, val2) { }

만약 자식클래스를 선언하면 val1, val2를 부모에게 전달해주므로써 부모클래스를 생성하고난이후 자식클래스를 생성한다. 

 

그림으로 보면 다음과 같다.

 

3.2 소멸자(Destructor)

소멸자는 객체가 소멸할때 마지막 최종작업을 기록하는 메소드를 말하며 아래 형식과 같다.

 

소멸자는 반환값, 전달받는 인자가 없고 ~클래스이름() 형태여야 한다.

 

주로 free, delete 등의 메모리 누수가 발생하지 않게 메모리 해제 작업등이 여기에 포함된다.

 

3.2.1 자식에서의 소멸자

자식에서 소멸자를 사용할경우 호출이 자식부터시작해서 부모로 끝나면서 소멸하게 된다.

 

즉 순서가 생성자와 반대이다.