gpt4 book ai didi

c++ - 如何实现不同参数结构的纯虚函数

转载 作者:搜寻专家 更新时间:2023-10-31 01:40:22 24 4
gpt4 key购买 nike

我正在构建一个名为 Database 的纯虚函数类。我的想法是拥有一个类来处理所有数据库接口(interface)(即:openclose)并且可以在我的业务层上使用。

Database 类将针对不同的数据库以多种“风格”实现,例如 mySqlDatabase 和 OracleDatabase。

我想象 Database 有没有代码的纯虚拟方法——只有一个头文件如下:

数据库.hpp

class Database {

public:
Database();
virtual ~Database();

virtual void open(const std::string databasename) = 0;
virtual void open(const std::string databasename, const std::string username, const std::string password) = 0;
virtual void open(const std::string databasename, const std::string schema, const std::string username, const std::string password) = 0;

.
<Other stuff>
.

}

三种 open 变体用于支持不同的数据库连接要求,从最简单的(如只需要一个文件名的 Sqlite3)到 Oracle(需要所有这些变量才能连接)。

我对实现有一些疑问(以oracle为例):

a) 我是否需要在派生类头文件中再次重新声明虚拟方法,例如:

    class  OracleDatabase : public Database {

public:
OracleDatabase ();
virtual ~OracleDatabase ();

void open(const std::string databasename);
void open(const std::string databasename, const std::string username, const std::string password);
void open(const std::string databasename, const std::string schema, const std::string username, const std::string password);
}

b) 如何在派生类中构建open 方法的实现(让我们以 Sqlite3 为例)?

void Sqlite3Database::open(const std::string databasename){
...do some stuff...
}

void Sqlite3Database::open(const std::string databasename, const std::string username, const std::string password) {
...do some stuff...
}

void Sqlite3Database::open(const std::string databasename, const std::string schema, const std::string username, const std::string password) {
...do some stuff...
}

我使用的策略是否正确?我一直在浏览虚拟和纯虚拟策略,认为这是解决我的问题的最佳方法。

有什么建议/提示吗?

OBS:我来自 C# 世界,所以如果这里有任何误解,我深表歉意。

最佳答案

对于编写查询函数(即所有数据库的相同接口(interface)),纯虚函数是可行的方法。

在这里,你试图写一个 open功能,您可能需要考虑 Factory Design Pattern : 你用我们的任何 open 编写你的数据库功能;然后你写了一个函数,比如 static std::unique_ptr<Database> Sqlite3Database::open(/*...*/) .

使用像您提倡的那样的虚函数不是一个好主意:无论如何,您有 3 个完全依赖于所使用的数据库的不同函数;更糟糕的是,你的母类依赖于它的子类:要添加一个具有另一种日志方案的新数据库,你必须向 Database 添加一个函数原型(prototype)。 .

另一种方法是使用纯虚函数(最好是 protected 并从构造函数中调用以保留 RAII;并在 NVI idiom 之后)将初始化字符串作为参数,例如作为 PDO 使用的那个.无论如何,数据库类型都可以从实例化的类型中推断出来,但想法是保留一个参数,以免有多个版本的 open

(旧答案保留了它试图解释的原则)

实际上你可以做得更简单:忘记 open , 并在 Sqlite3Database::Sqlite3Database(/* ... */) 中进行所有初始化.

毕竟,你无法在不知道它是哪种数据库的情况下打开数据库(因为你必须知道用户名/密码,甚至更多:你必须知道需要什么参数),所以有尝试从中创建虚拟纯函数是没有意义的。

那么,举个例子说明你可以做什么:

class Database {
public virtual void create(/* ... */) = 0;
// ...
};

class Sqlite3Database : public Database {
Sqlite3Database(string filename);
public virtual void create(/* ... */) override;
// ...
};

class MySqlDatabase : public Database {
MySqlDatabase(int host, short port, string username, string password);
public virtual void create(/* ... */) override;
};

关于c++ - 如何实现不同参数结构的纯虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29859228/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com