Virtual datatype / enum
I need a virtual class:
class Configuration
{
public:
enum EPromptId;
virtual CString getPrompt( EPromptId promptId ) = 0;
private:
};
So that each derived configuration can have its own set of EPromptIds
class Configuration1 : public Configuration
{
public:
enum EPromptId{
epid_HappyBirthday
};
CString getPrompt( EPromptId promptId ){
return "";
}
private:
};
class Configuration2 : public Configuration
{
public:
enum EPromptId{
epid_JummpingJehoshaphat
};
CString getPrompt( EPromptId promptId ){
return "";
}
private:
};
This fails because each class needs to inject a virtual function with a Configuration :: EPromptId parameter (not Configuration1 :: EPromptId or Configuration2 :: EPromptId as in this code).
Is it possible for the base class to recognize the type of the parameter but define the values โโdifferently in each derived class (perhaps not using an enum, but keeping it strongly typed, i.e. not using int).
EDIT: I want two different configurations for two different applications. Queries can be stored in the db table, but each "application" will have its own table. A pointer to the base configuration class is contained in the class that interacts with some hardware (i.e. the actual mapping). Hardware is an io device that can be used to request and receive user input. When the hardware class is created, it will be passed a pointer to the correct configuration class and hence display the correct queries when requested.
source to share
First: you need an abstract class. (An abstract class is one that has at least one pure virtual function. The virtual base class is the class from which it is virtual
derived.)
Then: No, what you want is impossible. You cannot forward an ad enum
and define it later, let alone define it differently. And even if you could: what happens if someone goes epid_HappyBirthday
into Configuration2
who doesn't know about it?
I suggest that you explain to us what you want to do (instead of what you thought you found how it works), and maybe someone can come up with an idiom to solve your problem.
source to share
You might be able to get most of what you want with templates ... until you hoped to store the collection Configuration*
and access them that way (you weren't, did you? Because you would need to know their types to know what to go through anyway ....)
template< typename ENUM_TYPE >
class Configuration
{
public:
virtual CString getPrompt( ENUM_TYPE promptId ) = 0;
private:
};
then
enum EPromptId{
epid_HappyBirthday
};
class Configuration1 : public Configuration< EPromptId >
{
public:
CString getPrompt( EPromptId promptId ){
return "";
}
private:
};
source to share
You cannot mix compilation type checking with runtime virtual function resolution.
You may have a common
class Configuration
{
public:
virtual CString getPrompt( int promptId ) = 0;
private:
};
and define two member functions in derivatives:
class Configuration1 : public Configuration
{
public:
enum EPromptId{
epid_HappyBirthday
};
CString getConfiguration1Prompt( EPromptId promptId ){
return "";
}
virtual CString getPrompt( int promptId )
{
return getConfiguration1Prompt(static_cast<EPromptId>(promptId));
}
private:
};
class Configuration2 : public Configuration
{
public:
enum EPromptId{
epid_JummpingJehoshaphat
};
CString getConfiguration2Prompt( EPromptId promptId ){
return "";
}
virtual CString getPrompt( int promptId )
{
return getConfiguration2Prompt(static_cast<EPromptId>(promptId));
}
private:
};
If you want to ensure validity promptId
, you must check it manually at runtime in your child classes.
This approach is not suitable anyway, because to use a generic function, getPrompt()
you need to know which child class you are using in order to access it EPromptId
.
source to share
My C ++ is a little rusty, but you can't do something like
struct EPromptId {
EPromptId() mId(sId++) { }
operator int() { return mId; }
friend static bool operator==(EPromptId lhs, EPromptId rhs) {
return lhs.mId == rhs.mId;
}
private:
int mId;
static int sId;
};
struct configuration1 {
static const EPromptId epid_HappyBirthday;
static const EPromptId epid_xxx;
CString getPrompt(EPromptId promptId ){
if (promptId == epid_HappyBirthday)
return "";
else if (promptId == epid_xxx)
}
}
// somewhere else
EPromptId configuration1::epid_HappyBirthday;
EPromptId configuration1::epid_xxx;
If you want to manage each id manually, just add a constructor and int
EPromptId (int id) mId (id) {}
and change the initialization to
EPromptId configuration1::epid_HappyBirthday = 1;
EPromptId configuration1::epid_xxx = 5;
source to share