c++ - 使用模板逻辑在运行时从基类转换为派生类

标签 c++ oop c++14 c++17

我正在编写一个小型数据库,似乎遇到了问题。我有 3 Statement类型(每个对应 CREATEINSERTSELECT 。这些类型的定义是:

class Statement { }; // Base class, contains common stuff like the table name

class CreateStatement : public Statement {
  /* Contains information regarding the CREATE statement after parsing (name and datatype of
  each column) */
}

class InsertStatement : public Statement {
  /* Contains information regarding the INSERT statement (list of values to enter inside the DB) */
}

class SelectStatement : public Statement {
  /* Contains information regarding the SELECT statement ( list of attributes to select from the DB) */
}
我的解析器具有适当解析这 3 种类型的输入语句的函数,但我从这些函数中的每一个返回基类。一个例子是:
Statement parse_create(const std::string& stmt) {
  CreateStatement response;
  // Parse stmt
  return response;
}
我这样做的理由是避免在我的主 REPL 循环中出现 if/else 情况(而不是检查输入是否属于 create 类型,然后有条件地返回 CreateStatement 或其他派生类,只需调用一次 parse 就会返回一个 Statement 对象)。我遇到的问题是执行返回的 Statement .我有 3 个不同的函数来执行这些命令( execute_createexecute_insertexecute_select ),它们分别将派生类作为参数( CreateStatementInsertStatementSelectStatement )。这样执行函数就可以在解析时利用存储在派生类对象中的信息。
我可以使用某种模板逻辑来调用适当的执行函数,还是在解析后返回基类后丢失派生类的信息?我尝试做一些类似的事情:
Statement parsed_stmt = parse(input); // input is the string the user entered
if (std::is_same_v<decltype(input), CreateStatement>) {
  execute_create(parsed_stmt);
}
但这显然行不通,因为类型是明确的 Statement .
我也将不胜感激有关设计的任何反馈。谢谢!

最佳答案

我这样做的方式是这样的:

class Statement {
    ...
    virtual void parse(const std::string &stmt) = 0; // A string view will work here too.
    virtual bool execute() = 0;
    ...
};

class Create : public Statement {
    ...
    virtual void parse(const std::string &stmt); // Implement
    virtual bool execute(); // Implement
    ...
};

... // more statements
然后在派生类中适本地实现这些。您可以解析非虚拟并调用虚拟 create方法,但这对我来说似乎是多余的。注释创建不返回任何内容 - 它只是更改对象的状态(存储语句或其他内容)。
同样,execute存储在派生类中,因此它知道如何执行自身 - 即使您引用了 Statement对象,正确的派生方法将被调用而无需额外的努力。我假设返回一个 bool 值表示成功。
这意味着您需要使用对语句的引用(或指针)。这是多态性继承的主要优势——能够以相同的方式对不同的派生对象进行操作,而不必担心它们究竟是什么。

关于c++ - 使用模板逻辑在运行时从基类转换为派生类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64003591/

相关文章:

c++ - 在 C++ 中访问成员对象的方法

java - 我应该总是从数据库中检索完整的对象吗?

c# - 有什么办法可以制造不同类型的敌人吗?

c++ - 回退到复制构造函数不起作用?

c++ - SFINAE 检查 operator[] 比我还糊涂?

传递数值时 fstream.h 中函数的 C++ 可移植性问题

c++ - std::引用对

javascript - 将带参数的方法添加到 javascript 对象

c++ - 我应该以什么顺序读取MSVC编译器的生成错误?

c++ - 将 MFC 中的一个大项目从 Visual C++ 6.0 迁移到 Visual Studio 2005