Access inherited member from base class? (C++)
I have a problem. This class is a base class for a basic enum handler:
Code:
#define ENUMOBJECT_BEGIN_ELEMENTS enum Element { Code:
class Enum : public EnumObject Code:
Enum e; However, is there a way that I could use a base class to modify an inherited class's data? |
Band-Aid Solution
I came up with a solution:
Code:
#define ENUMOBJECT_BEGIN(objectName) \ |
The thread name itself suggests you are trying to do a wrong thing. I.e. base classes are not supposed to know their children. I.e. your overall design/architecture appear to be wrong.
|
Quote:
Code:
class Base |
I hate the excessive use of #define in your first version. But the far more excessive abuse of #define in the second version is far worse.
When you want to do something like that with #define, you can almost always do something better with templates. Quote:
When you first see this, it will look impossibly circular. But C++ allows it and C++ compilers handle it correctly and it is a very powerful method to inject common functionality into multiple classses even when that functionality must be customized to each class. To make this easier for you to understand, I'll leave in the ugly #defines of your first version. I'm not taking the time to test this, so there might be a few details wrong. I've used this approach many times, so the approach is valid even if some details are wrong Code:
#define ENUMOBJECT_BEGIN_ELEMENTS enum Element { |
Indeed! I had just come to the same solution myself, and was about to go to bed after congratulating myself but stumbled upon your reply while checking my email. :)
Code:
template<typename Inherited> Quote:
Maybe I need to read my "Big C++" book, again... |
Quote:
Is there some purpose to defining enum Element{...} in the base class? So far as I understand, you never want to use that version of Element. I think my approach: typedef typename Actual::Element Element; is much more effective, because it makes Element in the base class be the actual type of Element in the actual class. With your version of Element in the base class, what is the purpose of private: Element e; That Element is the wrong type to use for values of Actual::Element What compiler are you using? I don't think the following line of your code is valid: EnumBase(Inherited::Element e = None); Older compilers will recognize that Inherited::Element is a type name and be able to parse that, but the C++ standard says they shouldn't, so newer compilers should not be able to parse that. Also, you have made None the wrong type, so that shouldn't compiler either. But I am impressed you thought of the main idea of inheriting from a base class that is templated by the inherited class. Had you seen that trick before? I would never have started using that myself if I hadn't seen it in other code. I would have assumed it was too circular to compile. |
Actually, yes, I do want to use the base class' Element enum, because only then may I provide two default elements: "None" (Unassigned) and "Default" without having to provide them in the inherited class.
I didn't compile the code when I put it here (I encountered the problems you have mentioned and fixed them when trying to compile), and I'm using GCC 4.5. And, you are right, it won't compile: Code:
../untitled/enumobject.h: In instantiation of ‘EnumObject<Enum>’: I'm becoming frustrated with C++'s lack of ingenuity... Is there a way to force the compiler to define Enum later? (extern keyword only works on variables or functions.) I'm tempted to create my own preprocessor, but it wouldn't be "standards compliant." |
Forget it. I'm just doing this from now on:
Code:
class Argument Code:
int main() Code:
class Argument Code:
class Argument |
All times are GMT -5. The time now is 09:57 AM. |