Convention for accessing inherited members eases development.
Index
When you are using a command prompt and wish to change to the "parent directory," you typically will type something
along the lines of "cd ..". Unfortunately, C++ offers no simple way of achieving
the same feature when dealing with classes. This tip explains a simple convention for accessing inherited members
through a relative naming scheme.
The gist of the idea is to always use typedef to create an alias for your base class,
and to always use the same alias. For example:
class base
{
base( base* owner )
};
class derived : public base
{
typedef base inherited;
derived( base* owner );
}
derived::derived( base* owner )
: inherited( owner )
{ }
Why would you go through the trouble, you ask? Well, suppose your class library is evolving. Shortly after implementing
a series of members in derived which all use services provided by
base, you realize you need to have an intermediate class,
intermediary which modifies the behavior of base. If you
had referenced base directly in all of the members of derived,
you would have to find and replace every single instance of the token base with the token
intermediary. If, however, you had used inherited to access
base's members, then you would only need to change the declaration of derived
and of derived::inherited, like so:
class base
{
base( base* owner );
};
class intermediary : public base
{
intermediary( base* owner );
};
class derived : public intermediary
{
typedef intermediary inherited;
derived( base* owner );
}
derived::derived( base* owner )
: inherited( owner )
{ }
Obviously, this sample is overly simplified and the convention described would not be very helpful. However, in more complex settings
this technique has proved quite useful.
typedef xxx inherited FAQs
- Q: Should I make the typedef private, public, or protected?
- A: This is really a matter of preference. If you use private, then only your class can traverse up its inheritence chain;
clients of the class, including derived classes, cannot. Furthermore, your class will only be able to traverse one level
up. If you use public, then anybody will be able to see from whence your class comes. With protected, only your class
and derived classes (assuming they derive publicly) will be able to traverse the inheritence chain.
- Q: Do I have to use the name inherited?
- A: Well, since this is a typedef where you provide the name, technically you don't. You could just as easily use dotdot,
parent, or base. However, we prefer inherited because when making a function call your code clearly indicates that you
are requesting behavior that your class inherits from its base class, like so:
// ...
inherited::do_something( );
// ...
- Q: Man you're smart! How'd you come up with this?
- A: Actually, back in school I used Delphi quite a bit. Borland's Object Pascal had a built in inherited keyword that worked
kinda like the inherited typedef does. When I started using C++ more often, I missed this little keyword but eventually
grew accustomed to working without it. Then I started using C++ Builder and noticed Borland using this typedef technique
in their VCL source code. Hallelujah! What a great idea!