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

C++子类专属静态常量实现与父类公共逻辑复用方案咨询

解决方案:使用CRTP(奇异递归模板模式)实现编译期静态多态

这是C++中针对这类需求最常用的实现方案,既可以保留父类的通用逻辑封装,又能让每个子类拥有独立的静态常量,同时支持静态方法直接调用。

实现代码

父类模板定义

#include <QString>
#include <QStringList>
#include <QSqlQuery>

template<typename Derived>
class AbstractTable
{
public:
    // 实例方法,供类实例调用
    void addRow() {
        // 通用逻辑直接复用静态常量,仅在父类实现一次即可
        QSqlQuery q;
        q.exec(QString("INSERT INTO %1 (%2) VALUES (...)")
            .arg(tableName())
            .arg(colNames().join(',')));
    }

    // 静态方法,支持直接通过子类类型调用
    static void addRowStatic() {
        QSqlQuery q;
        q.exec(QString("INSERT INTO %1 (%2) VALUES (...)")
            .arg(tableName())
            .arg(colNames().join(',')));
    }

    // 其他通用查询逻辑均可在父类统一实现
    static QString getSelectAllSql() {
        return QString("SELECT %1 FROM %2")
            .arg(colNames().join(','))
            .arg(tableName());
    }

private:
    // 每个子类类型对应独立的静态常量存储
    static const QString& tableName() {
        static const QString name = Derived::m_staticTableName;
        return name;
    }

    static const QStringList& colNames() {
        static const QStringList cols = Derived::m_staticColNames;
        return cols;
    }

    static const QString& identificationColumn() {
        static const QString col = Derived::m_staticIdentificationColumn;
        return col;
    }
};

子类实现

// 商品表子类
class ProductsTable : public AbstractTable<ProductsTable>
{
public:
    // 仅需声明当前表对应的静态常量,无需重复实现父类逻辑
    inline static const QString m_staticTableName = "products";
    inline static const QStringList m_staticColNames = {"id", "name", "price", "stock", "update_time"};
    inline static const QString m_staticIdentificationColumn = "id";
};

// 用户表子类
class UsersTable : public AbstractTable<UsersTable>
{
public:
    inline static const QString m_staticTableName = "users";
    inline static const QStringList m_staticColNames = {"uid", "username", "email", "reg_time", "status"};
    inline static const QString m_staticIdentificationColumn = "uid";
};

调用方式

// 静态调用,无需创建实例
ProductsTable::addRowStatic();
QString userSelectSql = UsersTable::getSelectAllSql();

// 实例调用,任意数量实例都不会重复存储表名、字段名等常量
ProductsTable productInst1, productInst2, productInst3;
productInst1.addRow();

兼容低版本C++的调整

如果使用的C版本低于C17,不支持类内inline static变量,只需将子类的静态常量放到类外的cpp文件中定义即可:

// ProductsTable.cpp中添加
const QString ProductsTable::m_staticTableName = "products";
const QStringList ProductsTable::m_staticColNames = {"id", "name", "price", "stock", "update_time"};
const QString ProductsTable::m_staticIdentificationColumn = "id";

方案优势

  • 无冗余存储:同一类型的所有表实例共享一套静态常量,内存占用和实例数量完全无关
  • 逻辑无重复:所有增删改查的通用逻辑都只在父类模板中实现一次,子类仅需声明自身的表配置
  • 支持静态调用:可直接通过子类类型调用静态方法操作对应表,符合需求
  • 运行效率高:基于编译期多态实现,无虚函数表的额外性能开销

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:57:03