[英]Convert from base to derived class at runtime using template logic
我正在編寫一個小型數據庫,似乎遇到了問題。 我有 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
。
我也很感激任何關於設計的反饋。 謝謝!
我這樣做的方式是這樣的:
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
對象的引用,也將毫不費力地調用正確的派生方法。 我假設返回一個布爾值來表示成功。
這意味着您需要使用對語句的引用(或指針)。 這是多態繼承的主要優勢——能夠以相同的方式對不同派生的對象進行操作,而不必擔心它們究竟是什么。
動態調度:
struct Base {
abstract virtual void method() = 0;
virtual ~Base() = default;
};
struct Derived: Base {
void method() override {}
};
靜態調度 (CRTP),通常是一種矯枉過正:
template <class D> struct Base {
void method() {
static_cast<D*>(this)->method();
}
};
struct Derived: Base<Derived> {
void method() { ... }
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.