S SmartDocs
Série: C++ cpp 236 linhas · Atualizado 2026-04-03

inheritance.cpp

C++/Part2_物件導向/Ch10_繼承與多型/inheritance.cpp

// ============================================================
// Ch10 — inheritance.cpp
// 繼承基礎:語法、建構解構順序、protected 成員、方法隱藏
// 編譯:g++ -std=c++17 -Wall -o inheritance inheritance.cpp
// ============================================================

#include <iostream>
#include <string>

// ────────────────────────────────────────────────────────────
// 1. 基本繼承語法與建構 / 解構順序
// ────────────────────────────────────────────────────────────

class Animal {
public:
    Animal() { std::cout << "  [Animal] 預設建構子\n"; }
    Animal(const std::string& name) : name_(name) {
        std::cout << "  [Animal] 建構: " << name_ << "\n";
    }
    ~Animal() { std::cout << "  [Animal] 解構: " << name_ << "\n"; }

    void eat() const { std::cout << "  " << name_ << " 正在進食\n"; }

    // protected 成員:衍生類別可存取,外部不可
protected:
    std::string name_ = "未命名";
    int age_ = 0;
};

class Dog : public Animal {
public:
    Dog() : Animal() {
        std::cout << "  [Dog] 預設建構子\n";
    }
    Dog(const std::string& name, const std::string& breed)
        : Animal(name), breed_(breed) {
        std::cout << "  [Dog] 建構: " << name_ << " (" << breed_ << ")\n";
    }
    ~Dog() { std::cout << "  [Dog] 解構: " << name_ << "\n"; }

    void bark() const {
        std::cout << "  " << name_ << " 汪汪叫!\n";  // 可存取 protected 成員
    }

    void info() const {
        std::cout << "  名字: " << name_
                  << ", 品種: " << breed_ << "\n";
    }

private:
    std::string breed_;
};

class Cat : public Animal {
public:
    Cat(const std::string& name, bool indoor)
        : Animal(name), indoor_(indoor) {
        std::cout << "  [Cat] 建構: " << name_ << "\n";
    }
    ~Cat() { std::cout << "  [Cat] 解構: " << name_ << "\n"; }

    void meow() const {
        std::cout << "  " << name_ << " 喵喵叫!\n";
    }

    void info() const {
        std::cout << "  名字: " << name_
                  << ", 室內貓: " << (indoor_ ? "是" : "否") << "\n";
    }

private:
    bool indoor_;
};

// ────────────────────────────────────────────────────────────
// 2. 方法隱藏(無 virtual 的情況)
// ────────────────────────────────────────────────────────────

class Base {
public:
    void speak() const { std::cout << "  Base::speak()\n"; }
    void greet() const { std::cout << "  Base::greet()\n"; }
};

class Derived : public Base {
public:
    // 隱藏了 Base::speak(),並非覆寫
    void speak() const { std::cout << "  Derived::speak()\n"; }
};

// ────────────────────────────────────────────────────────────
// 3. 多層繼承
// ────────────────────────────────────────────────────────────

class GuideDog : public Dog {
public:
    GuideDog(const std::string& name, const std::string& breed,
             const std::string& owner)
        : Dog(name, breed), owner_(owner) {
        std::cout << "  [GuideDog] 建構: " << name_ << " (主人: " << owner_ << ")\n";
    }
    ~GuideDog() { std::cout << "  [GuideDog] 解構: " << name_ << "\n"; }

    void guide() const {
        std::cout << "  " << name_ << " 正在引導 " << owner_ << "\n";
    }

private:
    std::string owner_;
};

// ────────────────────────────────────────────────────────────
// 4. Shape 階層示範 protected 成員
// ────────────────────────────────────────────────────────────

class Shape {
public:
    Shape(const std::string& color) : color_(color) {}

    void printColor() const {
        std::cout << "  顏色: " << color_ << "\n";
    }

protected:
    std::string color_;
};

class Rectangle : public Shape {
public:
    Rectangle(double w, double h, const std::string& color)
        : Shape(color), width_(w), height_(h) {}

    double area() const { return width_ * height_; }

    void print() const {
        std::cout << "  長方形 (" << color_ << "): "   // 存取 protected color_
                  << width_ << " x " << height_
                  << " = " << area() << "\n";
    }

private:
    double width_, height_;
};

class Circle : public Shape {
public:
    Circle(double r, const std::string& color)
        : Shape(color), radius_(r) {}

    double area() const { return 3.14159265 * radius_ * radius_; }

    void print() const {
        std::cout << "  圓形 (" << color_ << "): 半徑 "
                  << radius_ << " = " << area() << "\n";
    }

private:
    double radius_;
};

// ============================================================
// main
// ============================================================

int main() {
    std::cout << "========================================\n";
    std::cout << " 1. 建構與解構順序\n";
    std::cout << "========================================\n";
    {
        std::cout << "\n--- 建立 Dog ---\n";
        Dog d("小黑", "拉布拉多");
        d.eat();     // 繼承自 Animal
        d.bark();    // Dog 自己的方法
        d.info();
        std::cout << "\n--- 離開作用域,觀察解構順序 ---\n";
    }

    std::cout << "\n========================================\n";
    std::cout << " 2. Cat 繼承示範\n";
    std::cout << "========================================\n";
    {
        Cat c("小花", true);
        c.eat();
        c.meow();
        c.info();
        std::cout << "\n";
    }

    std::cout << "\n========================================\n";
    std::cout << " 3. 方法隱藏 (非多型)\n";
    std::cout << "========================================\n";
    {
        Derived d;
        Base* ptr = &d;

        std::cout << "  透過 Derived 物件呼叫:\n";
        d.speak();      // Derived::speak()

        std::cout << "  透過 Base* 指標呼叫:\n";
        ptr->speak();   // Base::speak() ← 靜態綁定

        std::cout << "  greet() 未被隱藏:\n";
        d.greet();      // 繼承的 Base::greet()
    }

    std::cout << "\n========================================\n";
    std::cout << " 4. 多層繼承(三層)\n";
    std::cout << "========================================\n";
    {
        std::cout << "\n--- 建立 GuideDog ---\n";
        GuideDog gd("Lucky", "黃金獵犬", "王先生");
        gd.eat();       // 來自 Animal
        gd.bark();      // 來自 Dog
        gd.guide();     // GuideDog 自己的
        std::cout << "\n--- 離開作用域 ---\n";
    }

    std::cout << "\n========================================\n";
    std::cout << " 5. Shape 階層與 protected 成員\n";
    std::cout << "========================================\n";
    {
        Rectangle rect(5.0, 3.0, "紅色");
        rect.print();
        rect.printColor();   // 繼承自 Shape

        Circle circ(4.0, "藍色");
        circ.print();
        circ.printColor();
    }

    std::cout << "\n========================================\n";
    std::cout << " 程式結束\n";
    std::cout << "========================================\n";

    return 0;
}

Artigos relacionados