9장 가상 함수와 추상 클래스

sua·2022년 4월 9일
0

명품 C++ Programming

목록 보기
1/10
post-thumbnail

1. 예제 9-1: 파생 클래스에서 함수를 재정의하는 사례

#include <iostream>
using namespace std;

class Base {
public:
    void f() { cout << "Base::f() called" << endl; }
};

class Derived : public Base {
public:
    void f() { cout << "Derived::f() called" << endl; }
};

void main() {
    Derived d, * pDer;
    pDer = &d; // 객체 d를 가리킨다.
    pDer->f(); //Derived의 멤버 f() 호출

    Base* pBase;
    pBase = pDer; //업캐스팅. 객체 d를 가리킨다.
    pBase->f(); //Base의 멤버 f() 호출
}

[실행 결과]

Derived::f() called

Base::f() called


2. 예제 9-2 : 오버라이딩과 가상 함수 호출

#include <iostream>
using namespace std;

class Base {
public:
    virtual void f() { cout << "Base::f() called" << endl; }
};

class Derived : public Base {
public:
    virtual void f() { cout << "Derived::f() called" << endl; }
};

void main() {
    Derived d, * pDer;
    pDer = &d; //객체 d를 가리킨다.
    pDer->f(); //Derived::f() 호출

    Base* pBase;
    pBase = pDer; // 업캐스팅. 객체 d를 가리킨다.
    pBase->f(); //동적 바인딩 발생!! Derived::f() 실행
}

[실행결과]

Derived::f() called

Derived::f() called


3. 예제 9-3 : 상속이 반복되는 경우 가상 함수 호출

#include <iostream>
using namespace std;

class Base {
public: virtual void f() { cout << "Base::f() called" << endl; }
};

class Derived : public Base {
public: void f() { cout << "Derived::f() called " << endl; }
};

class GrandDerived : public Derived {
public: void f() { cout << "GrandDerived::f() called" << endl; }
};

int main() {
    GrandDerived g;
    Base* bp;
    Derived* dp;
    GrandDerived* gp;
    bp = dp = gp = &g; // 모든 포인터가 객체 g를 가리킴

    bp->f(); // Base의 멤버 f() 호출 --> 결과는?
    dp->f(); // Derived의 멤버 f() 호출 --> 결과는?
    gp->f(); //GrandDerived의 멤버 f() 호출 --> 결과는?
}

[실행 결과]

GrandDerived::f() called

GrandDerived::f() called

GrandDerived::f() called


4. 예제 9-4 : 범위 지정 연산자를 이용한 기본 클래스의 가상 함수 호출

#include <iostream>
using namespace std;

class Shape {
public:
    virtual void draw() {
        cout << "--Shape--";
    }
};

class Circle : public Shape {
public:
    int x;
    virtual void draw() {
        Shape::draw(); //기본 클래스의 draw() 호출
        cout << "Circle" << endl;
    }
};

int main() {
    Circle circle;
    Shape* pShape = &circle;

    pShape->draw(); // 동적 바인딩 발생. draw()가 virtual이므로
    pShape->Shape::draw(); //정적 바인딩 발생. 범위 지정 연산자로 인해
}

[실행 결과]

--Shape--Circle

--Shape--


5. 예제 9-5 : 소멸자를 가상 함수로 선언

#include <iostream>
using namespace std;

class Base {
public:
    virtual ~Base() { cout << "~Base()" << endl; }
};

class Derived : public Base {
public:
    virtual ~Derived() { cout << "~Derived()" << endl; }
};

int main() {
    Derived* dp = new Derived();
    Base* bp = new Derived();

    delete dp; // Derived의 포인터로 소멸
    delete bp; // Base의 포인터로 소멸
}

[실행 결과]

~Derived()
~Base()
~Derived()
~Base()


6. 예제 9-6 : 추상 클래스 구현 연습

#include <iostream>
using namespace std;

class Calculator {
public:
    virtual int add(int a, int b) = 0; // 두 정수의 합 리턴
    virtual int subtract(int a, int b) = 0; // 두 정수의 차 리턴
    virtual double average(int a[], int size) = 0; // 배열 a의 평균 리턴. size는 배열의 크기
};

class GoodCalc : public Calculator {
public:
    int add(int a, int b) { return a + b; }
    int subtract(int a, int b) { return a - b; }
    double average(int a[], int size) {
        double sum = 0;
        for (int i = 0; i < size; i++)
            sum += a[i];
        return sum / size;
    }
};

int main() {
    int a[] = { 1,2,3,4,5 };
    Calculator* p = new GoodCalc();
    cout << p->add(2, 3) << endl;
    cout << p->subtract(2, 3) << endl;
    cout << p->average(a, 5) << endl;
    delete p;
}

[실행 결과]

5

-1

3

7. 추상 클래스를 상속받는 파생 클래스 구현 연습

#include <iostream>
using namespace std;

class Calculator {
    void input() {
        cout << "정수 2 개를 입력하세요>> ";
        cin >> a >> b;
    }
protected:
    int a, b;
    virtual int calc(int a, int b) = 0; //두 정수의 합 리턴
public:
    void run() {
        input();
        cout << "계산된 값은 " << calc(a, b) << endl;
    }
};

class Adder : public Calculator {
protected:
    int calc(int a, int b) { // 순수 가상 함수 구현
        return a + b;
    }
};

class Subtractor : public Calculator {
protected:
    int calc(int a, int b) { //순수 가상 함수 구현
        return a - b;
    }
};

int main() {
    Adder adder;
    Subtractor subtractor;

    adder.run();
    subtractor.run();
}

[실행 결과]

정수 2 개를 입력하세요>> 5 3
계산된 값은 8
정수 2 개를 입력하세요>> 5 3
계산된 값은 2

profile
가보자고

0개의 댓글