107 一般警察特考三等 警察資訊管理人員 物件導向程式設計 考古題詳解

107 年・一般警察特考・三等・警察資訊管理人員
試題代碼 物件導向程式設計

第 一 題25 分

表一為用來實現兩數運算的 C# 程式碼。Operation.cs 檔案定義了三個類別;IFactory.cs 定義了一個介面及兩個類別;Program.cs 則定義了 Program 類別。

【Operation.cs】

namespace FactoryPattern
{
    class Operation
    {
        private double _num1;
        private double _num2;

        public double Num1
        {
            get { return _num1; }
            set { _num1 = value; }
        }

        public double Num2
        {
            get { return _num2; }
            set { _num2 = value; }
        }

        public virtual double Result()
        {
            return 0;
        }
    }

    class OperationAdd : Operation
    {
        public override double Result()
        {
            return Num1 + Num2;
        }
    }

    class OperationMultiply : Operation
    {
        public override double Result()
        {
            return Num1 * Num2;
        }
    }
}

【IFactory.cs】

namespace FactoryPattern
{
    interface IFactory
    {
        Operation Create();
    }

    class AddFactory : IFactory
    {
        public Operation Create()
        {
            return new OperationAdd();
        }
    }

    class MultiplyFactory : IFactory
    {
        public Operation Create()
        {
            return new OperationMultiply();
        }
    }
}

【Program.cs】

namespace FactoryPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            IFactory operFactory = new AddFactory();
            Operation oper = operFactory.Create();

            oper.Num1 = 3;
            oper.Num2 = 5;

            Console.WriteLine(oper.Result());
        }
    }
}

請根據表一回答以下問題:

(一) 在 C# 語言中,關鍵字 namespace 的主要用途為何?(2 分)

(二) 程式進入點在那個類別的那個方法中?(2 分)

(三) 關鍵字 virtual 與 override 的主要用途為何?(2 分)

(四) class AddFactory : IFactory{....} 的意義為何?(2 分)

(五) IFactory operFactory = new AddFactory(); 這段程式碼用到了物件導向程式設計三大特性中的那一個特性?(2 分)

(六) 請依據表一的程式碼畫出 UML 類別圖。(15 分)

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題為典型的「物件導向程式設計(OOP)」與「軟體設計模式(Design Patterns)」整合題型,融合了 C# 程式語言特性、四人幫(GoF)的工廠方法模式(Factory Method Pattern),以及 UML 類別圖(Class Diagram) 之繪製規範。

  1. C# 語法與執行架構:
  • namespace(命名空間):邏輯組織與避免識別名稱衝突。
  • 程式進入點:通用語言執行平台(CLR)要求之 static void Main 簽章與宿主類別。
  • 多型機制關鍵字:virtual(宣告基底類別方法可被覆寫)與 override(衍生類別提供具體覆寫實作),構成動態晚期繫結(Late Binding)。
  • 介面實作語法:C# 統一以冒號 : 表達繼承與介面實作,若右側為介面則代表「實作(Realization)」。
  1. 物件導向三大特性(封裝、繼承、多型):
  • 介面與抽象型別參考指向實體物件(Upcasting)時,體現的是「多型(Polymorphism)」。
  1. UML 類別圖塑模規則:
  • 類別與介面表示法(三層結構:名稱、屬性、方法;<<interface>> 刻劃 stereotype)。
  • 可見性符號:-(private)、+(public)。
  • 關係線條與箭頭:
  • 泛化/繼承(Generalization):實線+空心三角形箭頭。
  • 實作(Realization):虛線+空心三角形箭頭。
  • 相依(Dependency / Instantiate):虛線+開放箭頭(--> 或 ..>)。

解題方法與逐題精解

(一) 在 C# 語言中,關鍵字 namespace 的主要用途為何?

  • 解題切入點:從軟體工程模組化與編譯器符號解析角度回答。
  • 解析:
  1. 防止名稱衝突(Naming Collisions):在大型專案或引用多個外部組件時,不同模組可能定義相同名稱的類別(例如不同程式庫皆有 Operation 類別)。透過命名空間作為前綴(如 FactoryPattern.Operation),可精準區隔識別碼。
  2. 組織與分類程式碼結構:依功能層次或子系統(如 UI、BLL、DAL)將關聯的類別、介面、結構及列舉進行邏輯分組,提升系統維護性與可讀性。

(二) 程式進入點在那個類別的那個方法中?

  • 解題切入點:檢視 C# 執行檔的入口常規規範。
  • 解析:
  • C# 應用程式(Console Application)在執行時期由 CLR 載入並啟動時,會尋找具有 static 修飾詞且名為 Main 的方法作為程式啟動的進入點。
  • 檢視表一之 Program.cs,進入點位於 Program 類別的 Main 方法(完整簽章為 static void Main(string[] args))。

(三) 關鍵字 virtual 與 override 的主要用途為何?

  • 解題切入點:動態分派(Dynamic Dispatch)與執行時期多型之配對機制。
  • 解析:
  1. virtual(虛擬):用於基底類別(父類別)的方法或屬性宣告中。其目的在於賦予該成員「多型能力」,向編譯器表明允許衍生類別在後續繼承時重新定義並改變其行為。未標記為 virtual、abstract 或 override 的成員,預設不可被覆寫。
  2. override(覆寫):用於衍生類別(子類別)的方法或屬性宣告中。其目的在於具體提供該虛擬成員的子類別專屬實作,取代(覆寫)繼承自基底類別的原有邏輯。
  3. 二者協同:兩者配對使用,使程式在執行時期依據變數所指向的「實際物件型別」而非「宣告型別」,動態決定要調用的方法實作(實現動態繫結)。

(四) class AddFactory : IFactory{....} 的意義為何?

  • 解題切入點:C# 語法冒號 : 後方接介面的語意分析。
  • 解析:
  • 語法意義:代表具體類別 AddFactory 實作(Implements) 了介面 IFactory。
  • 行為意義:介面在物件導向中充當合約(Contract)。此宣告代表 AddFactory 必須遵守 IFactory 所訂立的規格,負責將介面內定義的成員(在此為 Operation Create 方法)全部具體實作出來,否則無法通過編譯。

(五) IFactory operFactory = new AddFactory; 這段程式碼用到了物件導向程式設計三大特性中的那一個特性?

  • 解題切入點:物件導向三大特性為「封裝」、「繼承」、「多型」。分析變數宣告與指派的本質。
  • 解析:
  • 此行程式碼使用父介面型別 IFactory 宣告參考變數 operFactory,右側以具體子類別 AddFactory 進行實例化並指派。
  • 這種「以泛用介面操作具體實作物件」的機制稱為向上轉型(Upcasting),是多型(Polymorphism) 的核心展現。呼叫者端(operFactory)不需依賴特定類別,日後可抽換為 new MultiplyFactory,而後續程式碼皆以一致的介面呼叫,展現同一介面具備不同實作行為的特性。

(六) 請依據表一的程式碼畫出 UML 類別圖(15 分)

本題程式碼為標準「工廠方法模式(Factory Method Pattern)」,系統包含兩大階層架構與一個執行端:

  1. 運算階層(產品端 Product):
  • 抽象基底類別:Operation(包含私有欄位 _num1, _num2、公開屬性 Num1, Num2、虛擬方法 Result)。
  • 具體產品類別:OperationAdd 與 OperationMultiply,均繼承自 Operation 並覆寫 Result。
  1. 工廠階層(工廠端 Creator):
  • 介面:IFactory,定義抽象工廠方法 Create: Operation。
  • 具體工廠類別:AddFactory 與 MultiplyFactory,均實作 IFactory。
  1. 相依與使用關係:
  • AddFactory 在 Create 方法中建立 OperationAdd 實體,存在相依(Dependency / <<create>>)關係。
  • MultiplyFactory 在 Create 方法中建立 OperationMultiply 實體,存在相依(Dependency / <<create>>)關係。
  • Program 的 Main 方法使用 IFactory、AddFactory 及 Operation。
1. UML 類別圖(Mermaid 格式繪製)
🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

第 二 題25 分

佇列(Queue)是一種先進先出(First in first out, FIFO)的資料結構。我們想使用 C++ 語言及陣列來實作一個 QueueAsArray 類別,此類別宣告於 QueueAsArray.h 檔案中,程式碼如表二所示。表三為主函式 main() 的程式碼。

【表二:QueueAsArray 類別宣告的程式碼】

class QueueAsArray
{
public:
    QueueAsArray(int size);
    ~QueueAsArray();

    void enqueue(double data);    // 增加一個元素到 Queue 的後方
    void dequeue();               // 移除 Queue 的第一個元素
    void display();               // 列印 Queue 中的所有元素

private:
    int front;                   // Queue 第一個元素在陣列的位置
    int rear;                    // Queue 最後一個元素在陣列的位置
    int size;                    // Queue 中一共有多少個位置
    double* array;               // 用來儲存 Queue 元素的陣列之指標
    bool isFull();               // 檢查 Queue 是否已經填滿
    bool isEmpty();              // 檢查 Queue 是否是空的
};

【表三:主函式 main() 的程式碼】

int main()
{
    QueueAsArray* queue = new QueueAsArray(3);

    queue->enqueue(3);
    queue->enqueue(1);
    queue->enqueue(2);
    queue->enqueue(5);
    queue->enqueue(9);
    queue->dequeue();
    queue->enqueue(4);
    queue->display();

    system("pause");
    return 0;
}

enqueue() 的功能是把元素加入 Queue 的後方,dequeue() 的功能是移除 Queue 的第一個元素,display() 是列印 Queue 中所有的元素。圖一描述 QueueAsArray 中 enqueue 與 dequeue 的動作原理以及變數 front 及 rear 之變化情況。

(一) 請以 C++ 程式語言實現 QueueAsArray(int size)、~QueueAsArray()、enqueue()、dequeue()、display()、isFull()、isEmpty() 之功能,並將此程式碼存於 QueueAsArray.cpp 中。若物件使用到動態記憶體配置,則在執行解構子時要釋放該記憶體空間。(20 分)

(二) 根據表三,請問指標 queue 指向的佇列物件可儲存幾個元素?(2 分)

(三) 根據表三,請問程式執行完畢後,佇列內容為何?(3 分)

🖼️【此處有附圖,請對照原卷】

🖼️ 本題原卷含圖表。基於試題來源之版權考量,本站不轉載原卷影像; 題目文字已完整轉錄,圖表請自行參閱考選部公告之試題原檔。

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題評量物件導向程式設計(C++)​與資料結構(Data Structures)​的整合實作能力,核心觀念包含:

  1. 佇列(Queue)之先進先出(FIFO)特性:元素的加入發生在隊尾(rear),元素的移除發生在隊首(front)。
  2. 環狀佇列(Circular Queue)的陣列實作:使用一維陣列實作佇列時,若直接讓指標線性遞增,會因前方釋放的空間無法重複利用而產生「假溢位(False Overflow)」。因此需運用模數運算(Modulo Operation,即 % size)將陣列頭尾相接,形成環狀結構。
  3. 指標變數與邊界狀態定義:
  • 根據題幹表二註解,front 為「第一個元素在陣列的位置」,rear 為「最後一個元素在陣列的位置」。
  • 空佇列(Empty):初始或無元素時,設定 front=−1,rear=−1\text{front} = -1, \text{rear} = -1。
  • 滿佇列(Full):當下一個預備寫入的位置碰上隊首時,即 (rear+1)(modsize)==front(\text{rear} + 1) \pmod{\text{size}} == \text{front}。
  • 佇列僅剩單一元素時執行 dequeue,需將指標重設回空狀態(front=−1,rear=−1\text{front} = -1, \text{rear} = -1)。
  1. C++ 動態記憶體配置與解構子管理:使用 new[] 配發連續動態記憶體空間,在物件生命週期結束時,必須於解構子(Destructor)中使用 delete[] 正確釋放,避免記憶體洩漏(Memory Leak)。

解題方法

(一) QueueAsArray.cpp 程式碼實作

依據題目要求,需於 QueueAsArray.cpp 中完整實現各成員函式:

  • QueueAsArray(int size):配置大小為 size 的 double 動態陣列,並將 front 與 rear 初始化為 −1-1。
  • ~QueueAsArray:以 delete[] array 釋放動態配置的記憶體。
  • isEmpty:當 front==−1\text{front} == -1 時回傳 true,否則回傳 false。
  • isFull:當 (rear+1)(modsize)==front(\text{rear} + 1) \pmod{\text{size}} == \text{front} 時回傳 true,否則回傳 false。
  • enqueue(double data):先透過 isFull 檢查是否已滿;若為空佇列,將 front 與 rear 皆設為 00;若非空,則 rear=(rear+1)(modsize)\text{rear} = (\text{rear} + 1) \pmod{\text{size}},並將 data 存入 array[rear]。
  • dequeue:先透過 isEmpty 檢查是否為空;若佇列中僅剩一個元素(front==rear\text{front} == \text{rear}),移除後重設為空狀態(front=−1,rear=−1\text{front} = -1, \text{rear} = -1);若有多個元素,則將隊首後移:front=(front+1)(modsize)\text{front} = (\text{front} + 1) \pmod{\text{size}}。
  • display:若佇列不為空,由 front 開始循環狀索引依序輸出至 rear。
🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

第 三 題30 分

表四的程式碼是以多型的概念來實作圓形以及正方形的面積計算,請依據以下的要求進行程式碼的改寫:

(一) 將 Shape 類別修改成抽象類別。(3 分)

(二) 用常數函式的概念來避免在執行 getArea() 函式時,修改到 Circle 或 Square 物件成員的值。(3 分)

(三) 在 Circle 類別中,有一個圓周率 PI 的資料成員,這份程式碼的缺陷是,每生成一個 Circle 物件,就需要一塊記憶體來記錄 PI 值,造成記憶體的浪費,請用 static 成員的概念來改善 Circle 類別的程式碼。(3 分)

(四) 當幾何參數小於等於 0 時,執行 Circle 或 Square 的建構子時,物件依然能夠生成,但面積的計算會出錯,例如,當傳入的參數是 −2-2 時,生成的 Square 物件,執行 getArea() 後會傳回 44。這是類別設計上的瑕疵,為了改善這個狀況,應該利用靜態(static)方法的概念設計一個 Create() 的函數,當幾何參數小於等於 0 時,傳回 Null 指標,而當幾何參數大於 0 時,則呼叫該類別的建構子。(6 分)

【表四:Shape、Circle、Square 類別的程式碼】

【Shape.h】

class Shape
{
public:
    virtual double getArea()
    {
        return 0;
    }
};

class Circle : Shape
{
private:
    double const PI = 3.1415926;
    double _radius;

public:
    Circle(double radius);
    double getArea();
};

class Square : Shape
{
private:
    double _length;

public:
    Square(double length);
    double getArea();
};

【Shape.cpp】

#include "Shape.h"
#include <stdio.h>

Circle::Circle(double r)
{
    _radius = r;
}

double Circle::getArea()
{
    return PI * _radius * _radius;
}

Square::Square(double length)
{
    _length = length;
}

double Square::getArea()
{
    return _length * _length;
}

(五) 在表五中我們產生 10 個亂數,亂數的範圍是從 −3-3 到 66,我們把這 10 個亂數儲存在 data 陣列中。接下來我們利用 data 陣列的資料來產生 Circle 及 Square 物件,當陣列的 index 是偶數時產生 Circle 物件,奇數時產生 Square 物件,將這些物件以父類別指標 Shape* 的形式記錄下來,並將其加入到 vector 容器中。用 vector 的 iterator 功能將 vector 所有的物件取出計算其面積並加總,而後輸出結果。請以 C++ 語言完成表五的程式碼。(15 分)

登入後即可作答並保存紀錄。

這一題的完整詳解

本題為典型的 C++ 物件導向設計與標準樣板函式庫(STL)整合應用題,全面檢驗考生對於多型(Polymorphism)、抽象類別(Abstract Class)、常數保護(const-correctness)、靜態成員(Static Members)、簡單工廠模式(Static Factory Method)​以及 STL 容器與迭代器(Container & Iterator) 的實作能力。


核心觀念

  1. 抽象類別與純虛擬函式(Pure Virtual Function): 若基礎類別(Base class)僅定義介面規格而不提供具體實作,應將虛擬函式宣告為「純虛擬函式」(語法為 = 0;)。包含至少一個純虛擬函式的類別即為抽象類別,編譯器將禁止其實例化(Instantiation)。
  2. 常數成員函式(Const Member Function): 在成員函式宣告與定義的參數列後方加上 const 修飾字,編譯器會將該函式內隱含的 this 指標型別視為指向常數物件的指標(即 const ClassName* const this),藉此保證在該函式執行期間,物件的任何非 mutable 資料成員皆不可被修改。
  3. 靜態資料成員(Static Data Member): 靜態資料成員屬於「類別本身」而非屬於任何單一「物件實例」。所有物件共用同一塊記憶體位址,可大幅節省常數或共用資料的空間配置。在類別內部僅能進行宣告,必須在類別外部(通常在 .cpp 實作檔)配置空間並進行定義。
  4. 靜態工廠方法(Static Factory Method / Named Constructor Idiom): C++ 建構子本身無法直接回傳指標或空指標(NULL / nullptr)。當參數不合法時,除了拋出例外(Exception)外,標準的物件導向作法是引入靜態生成函式(如 Create),由其在堆疊或堆積上進行前置合法性檢查,確認無誤後才動態配置記憶體(new),否則傳回空指標。
  5. 多型存取權限與 STL 整合:
  • C++ 類別(class)預設繼承為 private。若要透過基礎類別指標(Shape*)操作衍生類別,繼承權限必須明確宣告為 public Shape,否則無法進行向上轉型(Upcasting)。
  • std::vector 為動態陣列容器,巡訪時應使用其所屬之 iterator 進行解參考操作。

解題方法

(一) 將 Shape 類別修改成抽象類別

  • 作法:在 Shape.h 中,將 getArea 宣告為純虛擬函式 virtual double getArea const = 0;。
  • 原因:圖形基礎類別無法預先得知具體圖形的面積計算方式,將其設為純虛擬函式可強制所有繼承的子類別(Circle、Square)必須實作該介面,同時使 Shape 成為無法直接產生物件的抽象類別。

(二) 使用常數函式避免修改物件成員

  • 作法:在基礎類別與衍生類別的 getArea 函式宣告及定義末端皆加上 const:
  • 宣告:virtual double getArea const = 0;、double getArea const;
  • 實作:double Circle::getArea const { ... }、double Square::getArea const { ... }
  • 原因:計算面積屬於查詢性質(Query)操作,加上 const 可在編譯時期提供型別安全保護,防止因邏輯疏失更動到 _radius 或 _length。

(三) 使用 static 成員改善 PI 的記憶體配置

  • 作法:
  • 在 Circle 類別中宣告 private: static const double PI;。
  • 在 Shape.cpp 全域區段進行空間配置與賦值:const double Circle::PI = 3.1415926;。
  • 原因:原程式碼在每個 Circle 物件實例中都保留一份 8 位元組(double)的常數 PI,造成冗餘。改為 static 後,整個行程僅保留單一記憶體複本,所有 Circle 實例共享此常數。

(四) 設計靜態生成方法 Create 作為防禦性設計

  • 作法:
  • 在 Circle 與 Square 類別中新增靜態方法: static Circle* Create(double radius); 及 static Square* Create(double length);。
  • 實作時先檢查幾何參數: 若參數 ≤0\le 0,直接傳回 NULL(或 C++11 的 nullptr); 若參數 >0> 0,則呼叫建構子透過 new 動態配置實例並回傳指標。

(五) 表五的主程式實作與多型加總

  • 作法:
  1. 亂數種子初始化:使用 srand(time(NULL));。
  2. 產生 10 個介於 −3-3 到 66 的亂數:亂數公式為 rand % 10 - 3(區間大小為 6−(−3)+1=106 - (-3) + 1 = 10)。
  3. 依據陣列索引奇偶性,分別呼叫 Circle::Create 與 Square::Create,並將合法的非空指標以 Shape* 形式存入 std::vector<Shape*>。
  4. 使用 std::vector<Shape*>::iterator 巡訪容器,累加 (*it)->getArea。
  5. 巡訪結束後輸出加總面積,並釋放動態配置的記憶體。

解題技巧

  1. 避開預設私有繼承陷阱: 原始題目的表四宣告為 class Circle : Shape。在 C++ 中,class 預設繼承為 private,若不修正為 public Shape,編譯器在執行 Shape* s = Circle::Create(...) 時會拋出無法將衍生類別轉換
🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

第 四 題20 分

複數 zz 的極座標表示法為 (r,θ)(r,\theta),其中 rr 為複數 zz 到原點的距離,將 zz 與原點連成的直線,此直線與實數軸的夾角為 θ\theta。我們可以將複數 zz 表示成 z=(r,θ)z=(r,\theta)。

若 z1=(r1,θ1)z_1=(r_1,\theta_1)、z2=(r2,θ2)z_2=(r_2,\theta_2),則複數的除法可以表示成:

z2z1=(r2r1,θ2−θ1)\frac{z_2}{z_1}=\left(\frac{r_2}{r_1},\theta_2-\theta_1\right)

請利用 C++ 程式語言實現複數極座標表示法的除法運算,程式之撰寫請依據以下要求:

(一) 複數之類別名稱為 Complex,有兩個 private 等級的資料成員,分別是 _radius 以及 _angle,_radius 代表 rr,_angle 代表 θ\theta。(3 分)

(二) 請用 inline 函數來實現資料成員的存取。(3 分)

(三) 實作運算子 /=(註:z2/=z1z_2/=z_1 等同於 z2=z2/z1z_2=z_2/z_1)。(4 分)

(四) 請設計一個 ComplexException 類別用來進行除零的例外處理,ComplexException 必須繼承 std::exception 並覆寫 what() 函式,當除 00 的情況發生時,丟出 DividedByZero 字串。(5 分)

(五) 請撰寫 main 函式來驗證程式之功能。(5 分)

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題為標準的 C++ 物件導向程式設計(OOP)實作題,評量考生對類別封裝、記憶體與效能最佳化、運算子多載及例外處理機制的整合應用能力:

  1. 類別封裝(Encapsulation):透過 private 修飾子隱藏內部狀態(_radius 與 _angle),確保資料完整性。
  2. 行內函式(inline Function):透過 inline 關鍵字向編譯器建議在呼叫端直接展開函式主體,以省去函式呼叫的堆疊(Stack Frame)開銷,常應用於簡短的取值(Getter)與設值(Setter)函式。
  3. 運算子多載(Operator Overloading):複合指定運算子(如 /=)的標準實作簽章為回傳自身的參考(Complex&),並以常數參考(const Complex&)接收運算元,以支援連續運算與避免不必要的物件複製。
  4. 自訂例外處理(Custom Exception):繼承標準函式庫的 std::exception,並覆寫(Override)虛擬函式 virtual const char* what const noexcept,實作標準化的例外錯誤回報機制。

解題方法

  1. 資料成員與存取介面設計:
  • 定義類別 Complex,於 private 區塊宣告 double _radius 與 double _angle。
  • 實作 Getter 與 Setter。明確加上 inline 關鍵字,Getter 函式必須加上 const 修飾以符合常數正確性(Const Correctness)。
  1. 運算子 /= 邏輯:
  • 依照極座標除法公式:z2z1=(r2r1,θ2−θ1)\frac{z_2}{z_1} = \left(\frac{r_2}{r_1}, \theta_2 - \theta_1\right)。
  • 運算前必須先檢查除數(右運算元)的半徑是否為 00;若為 00,則拋出(throw)ComplexException。
  • 若不為 00,則將當前物件的 _radius 除以除數的 _radius,當前物件的 _angle 減去除數的 _angle,最後回傳 *this。
  1. 例外類別 ComplexException:
  • 包含標頭檔 <exception>,讓 ComplexException 公開繼承 std::exception。
  • 覆寫 what 函式,回傳型別為 const char*,內容固定回傳 "DividedByZero"。
  1. 主函式 main 驗證:
  • 建立正常極座標複數並進行除法,輸出計算後結果。
  • 建立半徑為 00 的複數進行除法,並以 try-catch 區塊捕捉 ComplexException,印出 e.what 訊息以驗證例外攔截功能。

各小題實作要點解析

  • 第 (一) 小題(類別與成員宣告): 成員名稱必須嚴格符合題意 _radius 與 _angle,且必須置於 private 存取層級下,型態建議採用雙精度浮點數 double 以確保數值精確度。
  • 第 (二) 小題(inline 存取函式): 雖然直接在 C++ 類別宣告主體內部實作的成員函式編譯器會自動視為行內(implicitly inline),但為切合國考評分標準,程式碼中應明確寫出 inline 關鍵字。
  • 第 (三) 小題(運算子 /= 實作):
  • 函式簽章:Complex& operator/=(const Complex& rhs)。
  • 除數半徑為 00 時,除法無意義(極座標原點之夾角未定義且數值無限大),必須在此處觸發防禦性檢查。
  • 第 (四) 小題(ComplexException 與 what 覆寫):
  • 基礎類別宣告為 const char* what const noexcept(C++11 起)或 const char* what const throw(C++98)。覆寫時的簽章(包括後方的 const 與例外規範)必須完全相符,否則會被視為多載而非覆寫,導致多型(Polymorphism)失效。
  • 第 (五) 小題(main 函式功能驗證): 測試案例必須涵蓋兩大面向:「正常運算流程」與「引發除以零之例外捕捉流程」。

解題技巧與常見陷阱

  1. 運算子 /= 的回傳型態: 複合指定運算子必須回傳物件本體的參考(Complex&),即 return *this;。若寫成回傳 void 或傳值回傳(Complex),雖能通過單純賦值,但會違反 C++ 運算子慣例,無法支援如 (a /= b) /= c; 的語法,在考卷上會被扣分。
  2. what 函式簽章遺漏 const: std::exception::what 原型為 virtual const char* what const noexcept;。若遺漏後面的 const,當在 catch (const std::exception& e) 中透過常數參考呼叫 e.what 時,編譯器將報錯或無法呼叫到子類別實作。
  3. 除零判斷的精確度:
🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

其他考古題