将方法参数类型更改为子类中的派生类
Change method argument type to a derived class in child class
我正在创建一个数据库接口,并有两个不同的数据库实现来使用此接口
例如:
class DBOptions {
protected:
DBOptions();
};
class SQLliteDBOptions : public DBOptions { bool verySpecificSQLiteOption; };
class MySQLDBOptions : public DBOptions{ bool verySpecificMySQLOption; };
class DBIface {
public:
enum FileMode {
READ = 1,
WRITE = 2,
READWRITE = 3
};
public:
virtual bool connect(char * filename, DBIface::FileMode mode, DBOptions * opt) = 0;
virtual bool disconnect() = 0;
};
class SQLiteDB : public DBIface {
public:
bool connect(char * filename, DBIface::FileMode mode, SQLliteDBOptions * options)
{ std::cout << "connect form sqliten"; }
bool disconnect() { std::cout << "disconnect from sqliten"; }
};
class MySQLDB : public DBIface {
public:
bool connect(char * filename, DBIface::FileMode mode, MySQLDBOptions * options)
{ std::cout << "connect form mysqln"; }
bool disconnect() { std::cout << "disconnect from mysqln"; }
};
int main() {
DBIface * sqlitedb = new SQLiteDB();
SQLliteDBOptions * opt = new SQLliteDBOptions();
sqlitedb->connect("file", DBIface::READ, opt);
return 0;
}
两个派生类中connect
的方法不被视为父类中纯方法的实现。我应该怎么做才能解决此问题?
我希望我的类接受正确的数据库选项实例。我想我可以将 DB 选项动态转换为我需要的类型,但我想这不是最好的解决方案。
我是否应该创建一个 setter 方法来设置每个数据库实现的数据库选项?
我会说让选项参数成为派生数据库类型构造函数的参数。这样,派生类型就可以要求正确的选项类型,而不必担心匹配基签名。 只要选项参数在任何虚拟方法上,那么它就必须是相同的(或通过逆变的基类型(。
您必须在派生类中声明一个与纯虚拟方法 connect(( 具有相同参数的方法。也就是说,派生类也将被视为抽象类,除非您重写所有纯虚函数。
我尝试了SoronelHaetir提出的解决方案。正如预期的那样,它有效,我认为它以优雅的方式解决了您的问题。
class SQLiteDB : public DBIface{
public:
SQLiteDB(SQLliteDBOptions* opt) { pOtps = opt; }
bool connect(char * filename, SQLiteDB::FileMode mode)
{
std::cout << "connect form sqliten";
}
bool disconnect() { std::cout << "disconnect from sqliten"; }
private:
SQLliteDBOptions * pOtps;
};
int main() {
SQLliteDBOptions * opt = new SQLliteDBOptions();
DBIface * sqlitedb = new SQLiteDB(opt);
sqlitedb->connect("file", DBIface::READ);
return 0;
}
当然,抽象基类中的虚函数必须相应地修改:
virtual bool connect(char * filename, DBIface::FileMode mode) = 0;
我会完全摆脱connect
和disconnect
。此功能应分别移动到派生类的构造函数和析构函数。每个构造函数可能有不同的签名,这完全没问题,因为它们不是虚拟的。
这样,如果你有一个派生自DBIface
的对象,你可以绝对确定它是连接的。
此解决方案符合 RAII 习惯用法,因此可以推荐作为首选选项。
相关文章:
- 继承期间显示未知行为的子类
- 通过指向指针数组的指针访问子类的属性
- 从父类方法返回子类对象
- c++, 在子类中,如何在没有对象的情况下访问父类的方法?
- 将父类对象强制转换为子类的问题
- 避免在C++中重复子类定义
- 将QOpenGLWidget子类转换为使用Metal而不是OpenGL的子类是否可行?
- 如何初始化矢量的模板化子类
- C++ 继承:将子类传递给需要基类的函数并获取子类行为
- 有没有办法按值将纯抽象类的所有子类传递给 C++ 中的函数?
- 使用子类覆盖基类中定义的函数
- 子类地址等于虚拟基类地址?
- 如何在C++中找到变量派生最多的子类?
- 将方法参数类型更改为子类中的派生类
- C++ 函数无法使用模板为基类的子类派生模板
- 类和子类 - 从派生类发送到主要类的数据
- 采用指向基类的指针的函数是否也接受从基类私下派生的子类?
- C++,使用基类指针存储子类和使用派生类方法的策略
- 我怎样才能从模板派生两次,并让子类交互
- 隐藏从子类隐式派生自(c++)的方法