I have this:
class DATABASE_API MySQLConnection
{
}
And then a child class:
class DATABASE_API WorldDatabaseConnection : public MySQLConnection
{
}
Then I have this:
class GameDatabase {
public:
GameDatabase(PreparedStatement<MySQLConnection>* preparedStatement, GameDatabaseFlags gdf)
{
_gameObjectDatabaseFlag = gdf;
_preparedStatement = preparedStatement;
};
GameDatabaseFlags _gameObjectDatabaseFlag;
protected:
uint32_t versionId;
virtual void MapGameDatabase(GameDatabaseContainer gameDatabaseContainer) = 0;
PreparedStatement<MySQLConnection>* _preparedStatement;
};
When I try to initialize GameDatabase
like so:
PreparedStatement<WorldDatabaseConnection> * stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_GAMEOBJECTS_TEMPLATE);
auto gameDatabase = new GameDatabase(stmt,GAMEOBJECTS_DB);
I get the following error:
No matching constructor for initialization of 'GameDatabase'
Why is that? Can't I simple use the child class WorldDatabaseConnection
in place of the base class MySQLConnection
?
CodePudding user response:
Even though WorldDatabaseConnection
is a child class of MySQLConnection
, the template class PreparedStatement<WorldDatabaseConnection>
is not a child class of PreparedStatement<MySQLConnection>
.
CodePudding user response:
You are mixing up two distinct concepts: compile-time typing with a template vs. run-time typing with inheritance. As mentioned by Nielsen, PreparedStatement<WorldDatabaseConnection>
is not a child class of PreparedStatement<MySQLConnection>
.
However, you should be able to do this:
PreparedStatement<MySQLConnection> * stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_GAMEOBJECTS_TEMPLATE);
With appropriate casting, of course. You will certainly want to use dynamic_cast
in your class to extract the proper object. Whether you are in the habit of doing so in a constructor is your own choice.