[C++ 언어-막코딩] 14장 중복 다중 상속 클래스

in #kr-dev5 years ago (edited)

[C++ 언어-막코딩] 14장 중복 다중 상속 클래스



오늘은 다중 상속 클래스에서 중복 상속 클래스에 대해 알아보도록 하죠. 부모 클래스를 상속 받는 특정 자식 A클래스가 있을 때 다른 자식 B클래스가 부모 클래스와 A클래스를 동시에 상속을 받게 되는 경우고 이때 부모 클래스가 두번 상속 받게 되어 중복 클래스가 됩니다. 하지만 동일한 멤버 변수로 같은 이름의 두개의 변수가 생기게 되는데 이 부분을 해결하는 방법으로 클래스 앞에 virtual을 붙여 선언함으로 중복 문제를 해결합니다. 그러면 중복 클래스의 상황과 그 해결에 대해 간단히 살펴보도록 할까요.

1. 중복 클래스


class AAA {
public:
    int a;
public:
    AAA(){
        a=10;
        cout<<"생성자AAA"<<endl;
    }
    ~AAA(){
        cout<<"소멸자AAA"<<endl;
    }
    void output(){
        cout<<"a = "<<a<<endl;
    }   
};

class BBB : public AAA{
public:
    int b;
public:
    BBB(){
        b=20;
        cout<<"생성자BBB"<<endl;
    }
    ~BBB(){
        cout<<"소멸자BBB"<<endl;
    }
    void output(){
        cout<<"b = "<<b<<endl;
    }       
};
class CCC : public AAA, public BBB{
public:
    int c;
public:
    CCC(){
        c=30;
        cout<<"생성자CCC"<<endl;
    }
    ~CCC(){
        cout<<"소멸자CCC"<<endl;
    }
    void output(){
        cout<<"c = "<<c<<endl;
    }   
};

부모 AAA클래스가 자식 BBB 클래스에 상속 되고 CCC클래스는 AAA, BBB 클래스를 상속 받는 관계입니다. 이때 CCC은 두번 부모 AAA 클래스를 상속 받게 되는 상황이 됩니다. 이런 상황을 중복클래스라고 합니다. 위 코딩대로 했을 때 output() 멤버함수의 경우 어떻게 될까요. 지난 시간에 배운 오버라이팅 함수로 부모 클래스와 같은 동일한 이름을 자식 클래스에 있다면 자식클래스의 멤버 함수가 우선권을 갖고 재정의 됩니다. 멤버 함수의 경우는 중복 클래스와 상관없이 CCC클래스의 output()함수가 호출 됩니다.

실제 그렇게 출력되는지 볼까요.

CCC op1;
op1.output();

[결과]
a1.jpg

위 결과를 보면 부모 AAA 클래스가 중복 상속을 받게 되는 상황을 생성자, 소멸자 함수로 확인 할 수 있습니다. AAA 클래스의 생성자, 소멸자가 두번 호출 되었죠. 그리고 output()함수는 CCC클래스의 멤버 함수의 결과가 출력 되었네요.

여기까지는 별 문제 없습니다. 문제는 멤버변수입니다. 멤버변수의 경우는 AAA 클래스의 a변수가 두개가 존재하게 됩니다. BB클래스에서 상속받는 a변수와 AAA 클래스의 a변수는 동일 이름이지만 두개가 존재하게 됩니다. 그래서 CCC클래스에서는 a변수를 접근 할 때 어느 변수를 접근해야할지 모릅니다. 그래서 에러가 발생하지요.

그 부분에 대해 이야기를 이여 갈까요.

2. 중복클래스이 멤버변수 문제 해결


class CCC : public AAA, public BBB{
public:
    int c;
public:
    CCC(){
        c=30;
        cout<<"생성자CCC"<<endl;
    }
    ~CCC(){
        cout<<"소멸자CCC"<<endl;
    }
    void output(){
        cout<<"c = "<<a+b+c<<endl;
    }       
};

output()함수에서 a+b+c의 값을 출력 할 때 두개의 a중 어느 a를 선택하지 못합니다.

CCC op1;
op1.output();

실행을 하면 아래와 같이 에러가 발생합니다.

[결과]
a2.jpg

두개의 a 중 선택못하기 때문에 발생하는 에러이지요. 이문제를 virtual 선언을 통해 해결합니다. 이걸로 a를 재정의하는 개념으로 처리하면 해결됩니다.

class AAA{
};
class BBB : virtual public AAA{
};
class CCC : virtual public AAA, public BBB{
}

이렇게 선언함으로 AAA클래스의 멤버변수가 중복되더라고 상속 관계에서 a변수는 재정의 되어져 두개의 멤버 변수가 만들어 지지 않습니다.
코딩이 길어져서 클래스 명만으로 설명했는데 다음 전체소스로 오늘 내용을 종합해서 실습을 해보도록 하죠.

3. 코딩


[전체소스]

#include <iostream>
using namespace std;

class AAA {
public:
    int a;
public:
    AAA(){
        a=10;
        cout<<"생성자AAA"<<endl;
    }
    ~AAA(){
        cout<<"소멸자AAA"<<endl;
    }
    void output(){
        cout<<"a = "<<a<<endl;
    }   
};
class BBB : virtual public AAA{
public:
    int b;
public:
    BBB(){
        a=50;
        b=20;
        cout<<"생성자BBB"<<endl;
    }
    ~BBB(){
        cout<<"소멸자BBB"<<endl;
    }
    void output(){
        cout<<"b = "<<b<<endl;
    }       
};
class CCC : virtual public AAA, public BBB{
public:
    int c;
public:
    CCC(){
        c=30;
        cout<<"생성자CCC"<<endl;
    }
    ~CCC(){
        cout<<"소멸자CCC"<<endl;
    }
    void output(){
        cout<<"c = "<<a+b+c<<endl;
    }       
};

int main(int argc, char** argv) {
    CCC op1;    
    op1.output();
    
    return 0;
}

[결과]
a3.jpg

생성자 함수 호출을 보면 virtual 선언이 없다면 AAA 클래스가 두번 호출되지만 virtual 선언을 통해 AAA클래스는한번 호출되고 BBB 클래스가 최종 a변수값의 재정의 값이 되고 50으로 바뀌어 a+b+c가 100으로 출력됩니다.

마무리


중복클래스가 선언이 되었을 때 그 상황을 살펴보고 해결 방법을 알아보았습니다. 그런데 계속 클래스 코딩을 하는데 생성자, 소멸자함수를 넣을 필요가 없는 상황에도 코딩에 계속 넣고 실습하는 이유는 클래스의 변화를 확인하기 위해서입니다. 상속시 어떤 클래스가 먼저 호출되는지 상황을 확인 할 필요가 있습니다. 나중에 적응이 되면 필요시 생성자, 소멸자 함수를 사용하면 됩니다. 입문 하시는분들은 계속 위 코딩 생성자와 소멸자 체크 코딩을 넣어 주세요.


Sponsored ( Powered by dclick )

dclick-imagead

Sort:  

불금보내셔요~~^^

비오는 날씨자만 marsswim님도 불금 보내세요.

Thank you for your continued support towards JJM. For each 1000 JJM you are holding, you can get an additional 1% of upvote. 10,000JJM would give you a 11% daily voting from the 600K SP virus707 account.

Coin Marketplace

STEEM 0.18
TRX 0.14
JST 0.029
BTC 57729.24
ETH 3118.56
USDT 1.00
SBD 2.37