【发布时间】:2020-09-22 05:31:51
【问题描述】:
我正在编写一个小型数据库,似乎遇到了问题。我有 3 个Statement 类型(每个类型对应CREATE、INSERT 和SELECT。这些类型的定义是:
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_create、execute_insert 和 execute_select),它们分别将派生类作为参数(CreateStatement、InsertStatement 和 SelectStatement)。这样执行函数就可以在解析时利用存储在派生类对象中的信息。
我是否可以使用某种模板逻辑来调用适当的执行函数,或者在解析后返回基类后是否会丢失派生类的信息?我尝试做一些类似的事情:
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。
如果您对设计提供任何反馈,我也将不胜感激。谢谢!
【问题讨论】:
-
当您按值返回时,您 slice 对象。多态性仅适用于引用或指针。当然,这假设您的类层次结构是多态的。如果不是,那么在没有大量向上和向下转换的情况下,对基类的指针或引用将无法工作。
-
这类事情的首选工具是虚拟函数,而不是模板。你试过了吗?
-
您不能按值返回基本类型,它会分割您的对象并删除任何派生功能。欢迎使用 C++,由于糟糕的设计,功能相互争斗。