Advantages of typedef over derived class?
Simply put, what are the (or are there any) differences between doing say
class MyClassList : list<MyClass> { };
vs
typedef list<MyClass> MyClassList;
The only advantage that I can think of (and its what lead me to this question) is that with the derived class i can now easily forward declare MyClassList as
class MyClassList;
开发者_Go百科without compiler error, instead of
class MyClass;
typedef list<MyClass> MyClassList;
I can't think of any differences, but this made me wonder, are there cases in which a typedef can be used that a simple derived class can't?
Or to put it another way, is there any reason why I shouldn't change all my typedef list<...> SomeClassList; to the simple derived class so that I can easily forward declare them?
In C++ it is NOT recommended to derive from an STL container, so don't do it.
A typedef
is just creating an alias for an existing type, as it were, so typedef std::list<MyClass> MyClassList;
creates a "new type" that is called MyClassList
which you can now use as follows:
MyClassList lst;
Changing your typedef
s to a derived class is a bad idea. Don't do it.
typedef is intended exactly for this purpose -- to alias type names. Its very idiomatic and won't confuse anybody familiar with C++.
But to address why inheriting may be a bad idea.
std::list
does not have a virtual destructor. Meaning MyClassList
wouldn't have its destructor called when deleted through the base class. So this is typically frowned upon. In your case, you have no intention of putting any members in MyClassList, so this becomes a moot point until the next programmer sees inheritance as an invitation to add new members/override functions etc. They may not realize that std::list
's destructor is not virtual and not realize that in some cases MyClassList
's destructor won't get called.
Well, a typedef
can only do what its name suggests while a derived class can possibly be a full-blown makeover of its base(s). So while there may not be much of a difference if you limit yourself to "just" deriving (and not add any members, or override anything, etc) as far as the compiler is concerned, there might be a big difference as far as human readers of the code are concerned.
One might wonder "why is this a derived class when a typedef
would suffice"? Most people would assume that there must be a reason, so you would make life harder to the code's future maintainers. A typedef
, on the other hand, is a very specific tool and does not raise questions.
And while we 're on the topic of maintenance don't forget that as most things in C++, this "nothing will go wrong as long as we are disciplined and don't cross this line" is an open invitation to disaster. Since the compiler isn't there to stop you, someone, someday, will cross the line.
A number of things have been mentioned. A big thing however:
Deriving from a type does not inherit all the constructors.
If there are a number of non-default constructors, you won't have them when inheriting (you'd have to forward them to the base constructor).
Typedefs have no such 'issue'.
Now, typedefs do not generate unique typeids. If you want that, and not have the overhead or other disadvantages of inheritance, look at boost: it has a strong typedef macro that generates a unique typeid:
http://www.boost.org/doc/libs/1_37_0/boost/strong_typedef.hpp
A typedef is an alias, while a class is a new type. In the first case, the compiler has to simply replace MyClassList with list<MyClass>. In the second case, MyClassList involve the generation of default constructor, copy constructor assignment operator, destructor, and - where c++11 is in use - even move constructor and move assignment. In default cases, since MyClassList has no additional functionality, optimization will most likely wipe them out.
Note: I found the "deriving classes with non virtual destructor is not recommended" argument a weak one. A C++ developer should know that derivation does not necessarily imply polymorphism. A class that is not deleted through a pointer to its base doesn't need a virtual destructor, like a class whose method is not designed to be "called" through a base pointer does not require that method to be virtual. Simply, if a destructor is not virtual, don't treat that type as "polymorphic" on deletion. In this sense, destructor are not different from other virtual or non virtual methods. If this argument has to be considered strong, then, all classes that don't have "all virtual" method shouldn't be derived!
精彩评论