이 코드는 C++에서 상속에 대한 기본 개념을 설명하기 위한 예제입니다. 주석과 코드 자체를 분석하여 한 줄씩 정리해 드리겠습니다.

클래스 구조 및 상속 관계

class A
{

};
  • 클래스 A: 가장 기본이 되는 부모 클래스입니다. 현재 멤버가 정의되어 있지 않습니다.
class B0 : public A
{

};
class C0 : public B0
{

};
class C1 : public B0
{

};
  • 클래스 B0: A 클래스를 상속받은 클래스입니다.
  • 클래스 C0, C1: B0 클래스를 각각 상속받은 자식 클래스입니다.
class B1 : public A
{

};
class C0 : public B1
{

};
class C1 : public B1
{

};
  • 클래스 B1: A 클래스를 상속받은 또 다른 클래스입니다.
  • 클래스 C0, C1: B1 클래스를 각각 상속받은 자식 클래스입니다.

이로 인해 다음과 같은 상속 구조를 형성하게 됩니다:

          A
    B0        B1
  C0  C1    C2  C3

Base 클래스 정의

class Base
{
public:
    Base() : num(0)
    {
        cout << "Base" << endl;
    }
  • 기본 생성자: num 멤버 변수를 0으로 초기화하고, "Base"를 출력합니다.
    Base(int num) : num(num)
    {
        cout << "Base(" << num << ")" << endl;
    }
  • 매개변수가 있는 생성자: num을 인자로 받은 값으로 초기화하고, "Base(num)"를 출력합니다.
    virtual ~Base()
    {
        cout << "~Base" << endl;
    }
  • 가상 소멸자: 자식 클래스의 소멸자도 올바르게 호출되도록 가상 소멸자로 선언되어 있습니다. "Base" 소멸 시 메시지를 출력합니다.
    void func()
    {
        cout << num << endl;
    }
  • func 메서드: num의 값을 출력합니다.
    void set(int value)
    {
        num = value;
    }
    void add(int value)
    {
        num += value;
    }
  • setadd 메서드: num을 설정하거나 증가시키는 메서드입니다.
protected:
    int num;
private:
    int priNum;
protected:
    int proNum;
  • 멤버 변수:
    • num: protected 접근 지정자로 선언되어 자식 클래스에서 접근할 수 있습니다.
    • priNum: private으로 선언되어 자식 클래스에서도 접근할 수 없습니다.
    • proNum: protected로 선언되어 자식 클래스에서 접근 가능합니다.

Derived 클래스 정의

class Derived : public Base
{
public:
    Derived()
    {
        cout << "Derived" << endl;
    }
  • 기본 생성자: Derived 객체가 생성될 때 호출되며, "Derived"를 출력합니다. 부모 클래스의 기본 생성자가 먼저 호출됩니다.
    Derived(int num) : Base(num)
    {
        cout << "Derived(" << num << ")" << endl;
    }
  • 매개변수가 있는 생성자: 부모 클래스의 생성자를 호출해 num을 초기화하고 "Derived(num)"을 출력합니다.
    ~Derived()
    {
        cout << "~Derieved" << endl;
    }
  • 소멸자: "Derived" 소멸 시 메시지를 출력합니다.
    void foo()
    {
        func();
        this->func();

        num += 20;
        func();

        this->proNum = 30;
    }
  • foo 메서드:
    • 부모 클래스의 func 메서드를 호출해 num을 출력합니다.
    • num에 20을 더한 후 다시 func을 호출하여 변경된 num을 출력합니다.
    • proNum에 30을 할당합니다. (protected 멤버이므로 접근 가능)
    void func1()
    {

    }
};
  • func1 메서드: 현재 아무 동작도 하지 않는 빈 메서드입니다.

main 함수

int main()
{
    Base b;
    b.num = 10;
    b.func();
  • Base 객체 생성: 기본 생성자를 통해 Base 객체를 생성하고, num을 10으로 설정한 후 출력합니다.
    Derived d;
    d.num = 20;
    d.func();
    d.foo();
  • Derived 객체 생성: Derived 객체를 생성하고, num을 20으로 설정한 후 출력합니다.
  • foo 메서드를 통해 num을 20 증가시키고 다시 출력합니다.
    Base* base = new Derived;
  • 포인터 형식의 다형성: Base 형식의 포인터로 Derived 객체를 가리킵니다. 이는 부모 클래스가 자식 클래스를 가리킬 수 있다는 점을 보여줍니다.
    delete base;
  • 소멸자 호출: delete 연산자를 통해 Derived 객체를 삭제합니다. 자식 클래스의 소멸자가 먼저 호출되고, 부모 클래스의 소멸자가 나중에 호출됩니다.
    func(d);
}
  • 함수 호출: Base 타입의 참조자로 파라미터를 받는 func 함수에 Derived 객체를 전달합니다.

이 예제는 C++에서 상속의 기본 개념, 생성자와 소멸자의 호출 순서, protectedprivate 멤버 변수의 접근 가능 여부, 다형성을 활용한 객체 지향적 프로그래밍의 기본을 설명합니다.

profile
李家네_공부방

0개의 댓글