You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

国际象棋作业:Piece类静态Factory成员函数实现求助

解决Piece::Factory函数的高效实现问题

嘿,我来帮你搞定这个Factory函数的实现难题!既然要求不能用Clone、要高效避免多分支,那最适合的方案就是用函数指针映射表——通过数组直接索引创建函数,实现O(1)的查找效率,完全避开冗长的switch/if-else链。

核心思路

我们可以在Piece类的实现文件(比如Piece.cpp)里定义一组辅助创建函数,再用一个静态数组把PieceChar枚举值和对应的创建函数关联起来。因为PieceChar是基于char的枚举,直接用字符值做数组索引,效率拉满。

具体实现步骤

1. 定义辅助函数类型和创建函数

先在Piece.cpp里用匿名命名空间包裹所有辅助代码(避免污染全局命名空间),定义创建每个棋子的静态函数:

namespace {
// 定义创建函数的指针类型:接受Position引用,返回Piece*
using PieceCreator = Piece*(*)(const Position&);

// 白兵的创建函数
static Piece* CreateWhitePawn(const Position& pos) {
    return new Pawn(Colour::WHITE, pos);
}

// 黑兵的创建函数
static Piece* CreateBlackPawn(const Position& pos) {
    return new Pawn(Colour::BLACK, pos);
}

// 同理,为其他棋子类型实现创建函数(假设Knight、Bishop等子类已存在)
static Piece* CreateWhiteKnight(const Position& pos) {
    return new Knight(Colour::WHITE, pos);
}

static Piece* CreateBlackKnight(const Position& pos) {
    return new Knight(Colour::BLACK, pos);
}

static Piece* CreateWhiteBishop(const Position& pos) {
    return new Bishop(Colour::WHITE, pos);
}

static Piece* CreateBlackBishop(const Position& pos) {
    return new Bishop(Colour::BLACK, pos);
}

static Piece* CreateWhiteRook(const Position& pos) {
    return new Rook(Colour::WHITE, pos);
}

static Piece* CreateBlackRook(const Position& pos) {
    return new Rook(Colour::BLACK, pos);
}

static Piece* CreateWhiteQueen(const Position& pos) {
    return new Queen(Colour::WHITE, pos);
}

static Piece* CreateBlackQueen(const Position& pos) {
    return new Queen(Colour::BLACK, pos);
}

static Piece* CreateWhiteKing(const Position& pos) {
    return new King(Colour::WHITE, pos);
}

static Piece* CreateBlackKing(const Position& pos) {
    return new King(Colour::BLACK, pos);
}

// EMPTY对应的创建函数:返回nullptr
static Piece* CreateEmpty(const Position&) {
    return nullptr;
}
} // 匿名命名空间

2. 初始化静态映射数组

接着在同一个匿名命名空间里,创建一个静态数组,把PieceChar的字符值和对应的创建函数绑定:

namespace {
// ... 上面的创建函数 ...

// 静态映射数组:用char值作为索引,直接定位创建函数
static const PieceCreator creatorMap[256] = {
    nullptr, // 默认值,处理未定义的字符
    // 手动初始化枚举对应的位置
    [static_cast<char>(PieceChar::WHITE_PAWN)] = CreateWhitePawn,
    [static_cast<char>(PieceChar::WHITE_KNIGHT)] = CreateWhiteKnight,
    [static_cast<char>(PieceChar::WHITE_BISHOP)] = CreateWhiteBishop,
    [static_cast<char>(PieceChar::WHITE_ROOK)] = CreateWhiteRook,
    [static_cast<char>(PieceChar::WHITE_QUEEN)] = CreateWhiteQueen,
    [static_cast<char>(PieceChar::WHITE_KING)] = CreateWhiteKing,
    [static_cast<char>(PieceChar::BLACK_PAWN)] = CreateBlackPawn,
    [static_cast<char>(PieceChar::BLACK_KNIGHT)] = CreateBlackKnight,
    [static_cast<char>(PieceChar::BLACK_BISHOP)] = CreateBlackBishop,
    [static_cast<char>(PieceChar::BLACK_ROOK)] = CreateBlackRook,
    [static_cast<char>(PieceChar::BLACK_QUEEN)] = CreateBlackQueen,
    [static_cast<char>(PieceChar::BLACK_KING)] = CreateBlackKing,
    [static_cast<char>(PieceChar::EMPTY)] = CreateEmpty,
};
} // 匿名命名空间

3. 实现Factory函数

最后,在Piece.cpp里实现静态Factory函数:

Piece* Piece::Factory(PieceChar pieceChar, const Position& pos) {
    // 把枚举转成unsigned char,避免负索引问题
    unsigned char charVal = static_cast<unsigned char>(pieceChar);
    PieceCreator creator = creatorMap[charVal];
    
    // 如果找到对应的创建函数,调用它;否则返回nullptr
    if (creator) {
        return creator(pos);
    }
    return nullptr;
}

方案优势

  • 高效:数组索引是O(1)操作,比switch/if-else链快得多,尤其适合棋子类型固定的场景。
  • 符合要求:完全没有用到Clone函数,所有创建逻辑都是直接new对应子类实例。
  • 可维护:如果后续新增棋子类型,只需要添加对应的创建函数和映射项,不需要修改Factory函数本身。
  • 不修改类声明:所有辅助代码都在实现文件里,完全不碰头文件的类声明,满足你的限制条件。

内容的提问来源于stack exchange,提问作者clarence ng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:22:19