728x90

상속은 클래스 간 서로 관계를 가지면서 코드를 재사용하는 것입니다.

 

상속을 선언할 때는 상속을 받을 자식(파생) 클래스와 상속을 해줄 부모(기본) 클래스가 있어야 합니다.

class Parent
{
	...
};

class Child : public Parent
{
	...
};

예제 코드입니다.

 

child 클래스에서 parent 클래스를 상속받았습니다. child 클래스 안에서 parent 클래스의 멤버함수에 접근하고 있습니다. 

 

메인함수에서도 child 클래스의 인스턴스를 통해 parent 클래스의 멤버함수에 접근하고 있습니다.

#include <iostream>
using namespace std;

class Parent{
public:
    Parent() 
    { 
        cout << "Parent 생성자\n" ; 
        data = 0;
    }
    int getData() { return data ; }
    void setData(int data) 
    {
        this->data = data;
    }
protected:
    void printData() { cout << "data = " << data << endl; }
private:
    int data;
};

class Child : public Parent {
public:
    Child() { cout << "Child 생성자\n" ; }
    void Test()
    {
        printData();
        setData(5);
        cout << getData() << endl;
    }
};

/* 실행결과
Parent 생성자
Child 생성자
data = 0
5
10
*/

실행결과를 보면 생성자가 호출될 때 부모 클래스의 생성자가 먼저 호출되고 자식 클래스의 생성자가 호출되는 것을 볼 수 있습니다.

 

상속을 해주는 부모 클래스 앞에 접근 제어자인 public이 붙어 있습니다.

 

이 접근 제어자를 통해 자식 클래스와 호출 코드에서 어떻게 접근이 가능한 지 예제를 통해 자세히 알아보겠습니다.

접근 제어 지시자

 

먼저 public으로 상속을 해준 경우입니다.

 

이 경우에는 자식 클래스에서는 부모 클래스에서 private으로 선언된 함수만 접근이 불가능하고 메인 함수에서는 public으로만 선언한 함수만 선언이 가능합니다.

#include <iostream>
using namespace std;

class Parent{
public:
    Parent() { cout << "Parent 생성자\n" ; }
    void printPublic() { cout << "public\n" ; }
protected:
    void printProtected() { cout << "protected\n" ; }
private:
    void printprivate() { cout << "private\n" ; }
};

class Child : public Parent {
public:
    Child() { cout << "Child 생성자\n" ; }
    void CallParent() 
    {
        printPublic();
        printProtected();
        printprivate();		// 오류
    }
};

int main()
{
    Child c;
    c.printPublic();
    c.printProtected();		// 오류
    c.printprivate();		// 오류
    c.CallParent();
}

다음으로 protected로 상속을 해준 경우입니다.

 

이 경우에서는 메인함수에서 가능했던 Parent 함수의 printPublic()도 오류가 나게 됩니다.

#include <iostream>
using namespace std;

class Parent{
public:
    Parent() { cout << "Parent 생성자\n" ; }
    void printPublic() { cout << "public\n" ; }
protected:
    void printProtected() { cout << "protected\n" ; }
private:
    void printprivate() { cout << "private\n" ; }
};

class Child : protected Parent {
public:
    Child() { cout << "Child 생성자\n" ; }
    void CallParent() 
    {
        printPublic();
        printProtected();
        printprivate();     // 오류
    }
};

int main()
{
    Child c;
    c.printPublic();        // 오류
    c.printProtected();     // 오류
    c.printprivate();       // 오류
    c.CallParent();
}

 

 

마지막으로 private으로 상속을 해준 경우입니다.

 

protected와 마찬가지로 parent의 함수에는 모두 접근이 불가능한 것으로 보입니다.

#include <iostream>
using namespace std;

class Parent{
public:
    Parent() { cout << "Parent 생성자\n" ; }
    void printPublic() { cout << "public\n" ; }
protected:
    void printProtected() { cout << "protected\n" ; }
private:
    void printprivate() { cout << "private\n" ; }
};

class Child : private Parent {
public:
    Child() { cout << "Child 생성자\n" ; }
    void CallParent() 
    {
        printPublic();
        printProtected();
        printprivate();     // 오류
    }
};

int main()
{
    Child c;
    c.printPublic();        // 오류
    c.printProtected();     // 오류
    c.printprivate();       // 오류
    c.CallParent();
}

다음으로 메소드 재정의입니다. 메소드 재정의는 자식 클래스에서 부모 클래스의 메소드를 재정의하여 사용한다는 의미입니다. 영어로는 오버라이드(Override)라고 합니다.

 

오버로딩(Overloading) vs 오버라이딩(Overriding)

 

C++ 오버로딩과 오버라이딩

오버 로딩(overloading)은 함수 다중 정의를 말합니다. 함수 다중 정의는 함수 하나가 여러 의미를 갖는 것을 말합니다. 이름은 같아도 함수를 구성하는 매개변수의 타입이나 개수가 달라지게 되면 다른 함수로 취..

1d1cblog.tistory.com

예제 코드입니다. 부모 클래스에 있는 printData()를 자식클래스에서 다시 재정의 하였습니다. 

 

이럴경우 메인에서 Child 클래스의 인스턴스에서 printData()를 호출하면 Parent 클래스가 아닌 Child 클래스에서 printData()를 호출하게 됩니다. 

 

만약 부모 클래스의 printData()를 사용하고 싶을때는 아래와 같이 사용하면 됩니다.

#include <iostream>
using namespace std;

class Parent{
public:
    Parent() 
    { 
        cout << "Parent 생성자\n" ; 
        data = 0;
    }
    int getData() { return data ; }
    void setData(int data) 
    {
        this->data = data;
    }
    void printData() { cout << "data = " << data << endl; }
private:
    int data;
};

class Child : public Parent {
public:
    Child() { cout << "Child 생성자\n" ; }
    void printData() { cout << "override_data = " << Parent::getData() << endl;}
};

int main()
{
    Child c;
    c.setData(10);
    c.printData();
    c.Parent::printData();
}

/* 실행결과
Parent 생성자
Child 생성자
override_data = 10
data = 10
*/

 

 

728x90

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

C++ 빌더 패턴  (0) 2021.05.02
C++ 추상 팩토리 패턴  (0) 2021.05.02
C++ cout 자리수 지정하기  (0) 2020.02.28
C++ 큰따옴표(") 출력하기  (0) 2020.02.27
C++ 역슬래쉬(\) 출력하기  (0) 2020.02.27

+ Recent posts