Christof Warlich wrote:
Hi,
I'd like to define a class that should behave as much as posible
like std::string, but that has some small additional property:
class ExtendedString: public std::string {
public:
void someExtendedFunctionality(void) {}
};
As new classes do not inherit the constructors from its base, is
it true that I would have to define counterparts for all std::string
constructors that I may want to use to construct my derived class?
class ExtendedString: public std::string {
public:
void someExtendedFunctionality(void) {}
ExtendedString(const char *data): std::string(data) {}
ExtendedString(const std::string &data): std::string(data) {}
ExtendedString(void): std::string() {}
// ......
};
Or is there some smarter way to tell the compiler that the constructors
of std::string may be used right away, saving all the typing effort?
a) You can use templated constructors:
ExtendedString() : std::string() {}
template < typename A >
ExtendedString( A a ) : std::string( a ) {}
With std::string, I think you need to go up to 4 arguments.
b) It appears that your ExtendedString has no additional data members and
that the functionality provided by
void someExtendedFunctionality(void) {}
could as well be provided by a free-standing function. If so, a
free-standing functions is probably more appropriate. Maybe, you can even
come up with a generic implementation working on character-ranges. In that
case, you would have a more flexible addition to your library with less
code.
c) Many people frown upon public derivation from container classes. In my
opinion, it's not a deadly sin; but you should be aware of the possible
pitfalls:
1) Keep in mind that the destructor of std::string is non-virtual.
2) Note that functions like
std::string some_func( std::string const & str );
will happily accept ExtendedString objects as arguments, but they
will return std::string output. There are situations, where this
can get tricky.
Best
Kai-Uwe Bux