首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C++ 純虛函數與工廠模式常見錯誤解析

     編輯:程式設計疑難解答

問題背景

初學 C++ 時,純虛函數、抽象類、工廠模式的結合常導致編譯錯誤或運行時崩潰。本文針對一段典型錯誤代碼進行逐行分析,並給出現代 C++ 最佳實踐修正方案。

原始代碼存在的三大問題

1. 虛函數簽名不一致

// 基類
virtual void talk() const = 0;  // 帶 const

// 派生類
void talk() { ... }  // 缺少 const → 隱藏而非覆寫,導致派生類仍為抽象類

修正:派生類必須保持完全相同的簽名,包含 const 限定符。

2. 工廠返回值類型錯誤

Toy* getToy(string& type) {
    if (type == "Dog") { Dog *d; return d; }  // d 未初始化,返回野指針
    if (type == "Cat") { Cat *c; return c; }
}

問題:

  • 局部指針未 new 分配內存,返回懸空指針。
  • 裸指針所有權不明確,極易造成內存洩漏。

3. main 函數中工廠對象創建錯誤

ToyFactory *tf = new ToyFactory();  // 正確
ToyFactory tf = new ToyFactory();   // 錯誤:new 返回指針,不能賦值給值類型

現代 C++ 修正版(C++14/17)

#include <iostream>
#include <string>
#include <memory>  // unique_ptr
using namespace std;

class Toy {
public:
    virtual void talk() const = 0;
    virtual ~Toy() = default;  // 虛析構函數必須
};

class Dog : public Toy {
public:
    void talk() const override { cout << "Wow" << endl; }
};

class Cat : public Toy {
public:
    void talk() const override { cout << "Meow" << endl; }
};

class ToyFactory {
public:
    // 返回 unique_ptr 自動管理生命週期
    unique_ptr<Toy> getToy(const string& type) {
        if (type == "Dog") return make_unique<Dog>();
        if (type == "Cat") return make_unique<Cat>();
        return nullptr;
    }
};

int main() {
    string type = "Dog";
    ToyFactory factory;  // 棧上分配,無需 new
    auto toy = factory.getToy(type);
    if (toy) toy->talk();
    return 0;
}

關鍵改進點解析

項目原寫法現代寫法優勢
虛函數簽名缺少 constoverride + const編譯期檢查,防止隱藏
內存管理裸指針 + 手動 new/deleteunique_ptr + make_uniqueRAII,零內存洩漏
工廠對象new ToyFactory()棧上 ToyFactory factory自動析構,异常安全
參數傳遞string&const string&接受臨時對象,語義更清晰

總結

C++ 多態的核心在於虛函數簽名完全一致與所有權語義明確。採用智能指針、override 關鍵字、值語義工廠,能從語言層面消除一大類資源管理 Bug,寫出更健壯的代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved