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?
Even though WorldDatabaseConnection is a child class of MySQLConnection, the template class PreparedStatement<WorldDatabaseConnection> is not a child class of PreparedStatement<MySQLConnection>.
Related
I have a user class that has a member pointer to a data class. But I want to implement a derivedUser that extends user, but it also needs to have additional data which is stored in a derivedData class, it would look something like this:
class Data {
/*...the stored data...*/
}
class DerivedData : public Data {
/*...the additional data...*/
}
class User {
public:
/*...some methods that use dp...*/
protected:
Data* dp;
}
class DerivedUser : public User {
public:
/*...even more methods that use ddp...*/
protected:
DerivedData* ddp;
}
But here is the problem: With the way I've set it up the DerivedUser class would store two pointers of different types pointing to the same object, which is not optimal. The DerivedUser should only store one pointer, and it should know that it is of the type DerivedData and fail if it is given the wrong type of data. And the question is: how do I implement this?
Ive tried:
class DerivedUser : public User {
public:
/*...even more methods that use ddp...*/
protected:
DerivedData* ddp = dynamic_cast<DerivedData*>(dp);
}
I see that you want DerivedUser to have DerivedData in its constructor.
Because of polymorphism a parent class can references it child class. So this is legal:
Data* dp = new DerivedData();
Here is the solution you are looking for:
class User {
public:
/*...some methods that use dp...*/
User(Data* dp){
this->dp = dp;
}
protected:
Data* dp;
};
class DerivedUser : public User {
public:
/*...even more methods that use ddp...*/
DerivedUser(DerivedData *dp) : User(dp) {
}
};
Now, DerivedUser points to your DerivedData class
Here:
int main(){
DerivedData* dp = new DerivedData();
DerivedUser* user = new DerivedUser(dp);
return 0;
}
Add a method DerivedData* GetData() in the DerivedUser class
DerivedData* GetData()
{
return static_cast<DerivedData>(dp);
}
You can make sure dp is a DerivedData* if the constructor of DerivedUser looks like this:
DerivedUser(DerivedData* d):User(d){}
Here is the full code:
class Data {
/*...the stored data...*/
}
class DerivedData : public Data {
/*...the additional data...*/
}
class User {
public:
User(Data* d):dp(d){}
/*...some methods that use dp...*/
protected:
Data* dp;
}
class DerivedUser : public User {
public:
DerivedUser(DerivedData* d):User(d){}
/*...even more methods that use ddp...*/
protected:
DerivedData* GetData(void)
{
return static_cast<DerivedData*>(dp);
};
}
I am having trouble converting a pointer to a templated derived class to a base class pointer for the purposes of storing in a map(and obviously retrieving it later.). I have:
#include <map>
//Role.h
class RoleBase{};
enum class RoleEnum : int;
template<RoleEnum role>
class Role : public RoleBase{};
//Relationship.h
class Relationship{
public:
template<RoleEnum role>
Role<role>* getRole(){
auto it=RoleMap.find(role);
if ( it == RoleMap.end() ) {
return nullptr;
} else {
RoleBase* roleBase= it->second;
return static_cast<Role<role>* >(roleBase);
}
}
std::map<RoleEnum,RoleBase*> RoleMap;
};
//squash.h
enum class RoleEnum : int
{
Player,
Referee
};
template<> class Role<RoleEnum::Player>{};
template<> class Role<RoleEnum::Referee>{};
class SquashGame: public Relationship{
public:
SquashGame(){
RoleBase* playerRole=new Role<RoleEnum::Player>; //problematic
RoleMap.emplace(RoleEnum::Player,playerRole);
}
};
int main() {
SquashGame squashGame;
squashGame.getRole<RoleEnum::Player>();
return 0;
}
Why is that and is there a way of fixing that so I can template a class with enum values for the purposes of calling externally by a getClass<Enum> function, as is hopefully clear in the example?
The problem is simple: your redefinition of Role
template<> class Role<RoleEnum::Player> {}
Doesn't extend RoleBase.
Either remove it or change it to:
template<> class Role<RoleEnum::Player> : public RoleBase {}
I have a AbstractFactory, WinFactory and IOSFactory classes.
AbstactFactory inheritences WinFactory and IOSFactory as the following:
class IOSFacetory {
private:
IOSRectButton *_rectbtn;
IOSCircularButton *_circbtn;
public:
IOSFacetory() : _rectbtn(NULL), _circbtn(NULL) {} // set rectbtn to null
IOSRectButton* getIOSRectBtn () {
if(!_rectbtn) _rectbtn = new IOSRectButton;
return _rectbtn;
}
IOSCircularButton* getIOSCircBtn() {
if(!_circbtn) _circbtn = new IOSCircularButton;
return _circbtn;
}
~IOSFacetory() {
if(_rectbtn) delete _rectbtn;
if(_circbtn) delete _circbtn;
}
};
class WinFacetory {
private:
WinRectButton *_rectbtn;
WinCircularButton *_circbtn;
public:
WinFacetory() : _rectbtn(NULL), _circbtn(NULL) {} // set rectbtn to null
WinRectButton* getWinRectBtn () {
if(!_rectbtn) _rectbtn = new WinRectButton;
return _rectbtn;
}
WinCircularButton* getWinCircBtn() {
if(!_circbtn) _circbtn = new WinCircularButton;
return _circbtn;
}
~WinFacetory() {
if(_rectbtn) delete _rectbtn;
if(_circbtn) delete _circbtn;
}
};
class AbstractFactory : public WinFacetory, public IOSFacetory {
public:
AbstractFactory(){}
};
in the main function, I'm trying to set a IOSFactory into a AbstractFactory Pointer:
#include "AbstractFactory.h"
int main() {
#ifdef _WIN
AbstractFactory* factory = new WinFacetory;
#else
AbstractFactory* factory = new IOSFacetory;
#endif
std::cin.get();
return 0;
}
It doesn't work and I get the following compilation error:
IntelliSense: a value of type "IOSFacetory *" cannot be used to initialize an entity of type "AbstractFactory *.
I guess I have a minor error but I can't figure it out. I'd like to get helped. thanks!
You should reverse your inheritance relations. AbstractFactory should be a base class of both IOSFactory and WinFactory.
Remember to declare a virtual destructor in the base class.
You should derive WinFacetory and IOSFacetory from AbstractFactory. Now you do it contrariwise.
I have a class template in a c++ project:
template<class RequestHandler = DefaultRequestHandler>
class Server { ... }
I then have another class in which I want to hold an instance of Server<WhateverRequestHandlerIWant> as a property. So currently I have something like:
class OtherClass {
public: Server<>* server;
};
Unless I am mistaken, this will only allow me to store Server classes in which the template parameter is the class DefaultRequestHandler, correct?
Is there a way to write this without just making OtherClass a class template as well?
You could add a common abstract class for all server-like classes:
class IServer { ... };
then
template<class RequestHandler = DefaultRequestHandler>
class Server : virtual public IServer { ... }
and
class OtherClass {
public: IServer* server;
};
I'm looking for solution of C++ class design problem. What I'm trying to achieve is having static method method in base class, which would return instances of objects of descendant types. The point is, some of them should be singletons. I'm writing it in VCL so there is possibility of using __properties, but I'd prefer pure C++ solutions.
class Base {
private:
static Base *Instance;
public:
static Base *New(void);
virtual bool isSingleton(void) = 0;
}
Base::Instance = NULL;
class First : public Base { // singleton descendant
public:
bool isSingleton(void) { return true; }
}
class Second : public Base { // normal descendant
public:
bool isSingleton(void) { return false; }
}
Base *Base::New(void) {
if (isSingleton())
if (Instance != NULL)
return Instance = new /* descendant constructor */;
else
return Instance;
else
return new /* descendant constructor */;
}
Arising problems:
how to declare static variable Instance, so it would be static in descendant classes
how to call descendant constructors in base class
I reckon it might be impossible to overcome these problems the way I planned it. If so, I'd like some advice on how to solve it in any other way.
Edit: some minor changes in code. I have missed few pointer marks in it.
Just to check we have our terminologies in synch - in my book, a factory class is a class instances of which can create instances of some other class or classes. The choice of which type of instance to create is based on the inputs the factory receives, or at least on something it can inspect. Heres's a very simple factory:
class A { ~virtual A() {} };
class B : public A {};
class C : public A {};
class AFactory {
public:
A * Make( char c ) {
if ( c == 'B' ) {
return new B;
}
else if ( c == 'C' ) {
return new C;
}
else {
throw "bad type";
}
}
};
If I were you I would start again, bearing this example and the following in mind:
factorioes do not have to be singletons
factories do not have to be static members
factories do not have to be members of the base class for the hierarchies they create
factory methods normally return a dynamically created object
factory methods normally return a pointer
factory methods need a way of deciding which class to create an instance of
I don't see why your factory needs reflection, which C++ does not in any case support in a meaningful way.
Basing this on the answer by #Shakedown, I'll make Base be templated on the actual type, using the CRTP:
template <class T>
class Base
{
public:
static std::auto_ptr<Base<T> > construct()
{
return new T();
}
};
class First : public Base<First>
{
};
class Second : public Base<Second>
{
};
This is nice because construct is now once again a static member. You would call it like:
std::auto_ptr<First> first(First::construct());
std::auto_ptr<Second> second(Second::construct());
// do something with first and second...
You can create a Singleton class and a NonSingleton class, and make all the descendants inherit one of them.
class Base {
public:
static Base *New() = 0;
}
class SingletonDescendant: public Base {
public:
*Base::New() {
if (Instance != NULL)
return Instance = new /* descendant constructor */;
else
return Instance;
}
private:
static Base *Instance;
}
SingletonDescendant::Instance = NULL;
class NonSingletonDescendant: public Base {
public:
*Base::New() {
return new;
}
}
class First : public SingletonDescendant{ // singleton descendant
}
class Second : public NonSingletonDescendant{ // normal descendant
}
It solves the issues that you raised:
How to declare static variable Instance, so it would be static in descendant classes: It exists only in the SingletonDescendant class.
How to call descendant constructors in base class: Using the New function
I have to write construct() method in every descendant; I consider it redundant, as it is obvious what it has to do: Now it is only in SingletonDescendant and NonSingletonDescendant.
How about something like this:
class Base
{
public:
virtual Base construct() = 0;
};
class First : public Base
{
public:
Base construct(){ return First(); // or whatever constructor }
};
class Second : public Base
{
public:
Base construct(){ return Second(...); // constructor }
};