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
相关产品推荐
相关产品推荐

