简体   繁体   中英

Extending libraries in C++

Is it possible to extend a class from a C++ library without the source code? Would having the header be enough to allow you to use inheritance? I am just learning C++ and am getting into the theory. I would test this but I don't know how.

Short answer YES, definitively you can.

Long answer : WARNING: THe following text may hurt children an sensitive OOP integralists. If you feel or retain to be one of such, stay away from this answer: mine your and everyone alse life will be more easier

Let me reveal a secret: STL code is just nothing more than regular C++ code that comes with headers and libraries, exactly like your code can -and most likely- do. STL authors are just programmer LIKE YOU. They are no special at all respect to the compiler. Thay don't have any superpower towards it. They sits on their toilet exacly like you do on yours, to do exactly what you do. Don't over-mistify them.

STL code follows the exact same rules of your own written code: what is overridden will be called instead of the base: always if it is virtual, and only according to the static type of its referring pointer if it is not virtual, like every other piece of C++ code. No more no less.

The important thing is not to subvert design issues respecting the STL name convention and semantics, so that every further usage of your code will not confuse people expectation, including yourself, reading your code after 10 years, not remembering anymore certain decisions.

For example, overriding std::exception::what() must return an explanatory persistent C string, (like STL documentation say) and not add unexpected other fuzzy actions.

Also, overriding streams or streaming operators shold be done cosidering the entire design (do you really need to override the stream or just the streambuffer or just add a specific facet to the locale it imbued?): In other words, study not just "the class" but the design of all its "world" to properly understand how it works with what is around.

Last, but not least, one of the most controversial aspect are containers and everything not having virtual destructors.

My opinion is that the noise about the "classic OOP rule: Dont' derive what has no virtual destructor" is over-inflated: simply don't expect a cow to became an horse just because you place a saddle on it.

If you need (really really need) a class that manage a sequence of character with the exact same interface of std::string that is able to convert implicitly into an std::string and that has something more, you have two ways:

  • do what the good good girls do, embed std:string and rewrite all its 112 (yes: they are more than 100) methods with function that do nothing more than calling them and be sure you come still virgin to the marriage with another good good boy programmer's code, or ...
  • After discover that this takes about 30 years and you are risking to become 40 yo virgin no good good boy programmer is anymore interested in, be more practical, sacrifice your virginity and derive std::string . The only thing you will loose is your possibility to marry an integralist. And you can even discover it not necessarily a problem: you're are even staying away from the risk to be killed by him!

The only thing you have to take care is that, being std::string not polymorphic your derivation will mot make it as such, so don't expect and std::string* or std::string& referring yourstring to call your methods, including the destructor, that is no special respect every other method; it just follow the exact same rules. But ... hey, if you embed and write a implicit conversion operator you will get exactly that result, no more no less!

The rule is easy: don't make yourself your destructor virtual and don't pretend "OOP substitution principle" to work with something that is not designed for OOP and everything will go right.

With all the OOP integralist requemscant in pacem their eternal sleep, your code will work, while they are still rewriting the 100+ std::string method just to embed it.

Yes, the declaration of the class is enough to derive from it.

The rest of the code will be picked up when you link against the library.

Yes you can extend classes in standard C++ library. Header file is enough for that.

Some examples:

  • extending std::exception class to create custom exception
  • extending streams library to create custom streams in your application

But one thing you should be aware is don't extend classes which does not have a virtual destructor . Examples are std::vector , std::string

Edit : I just found another SO question on this topic Extending the C++ Standard Library by inheritance?

Just having an header file is enough for inheriting from that class.
C++ programs are built in two stages:

  • Compilation
    Compiler looks for definition of types and checks your program for language correctness.This generates object files.
  • Linking
    The compiled object files are linked together to form a executable.

So as long as you have the header file( needed for compilation ) and the library( needed for linking ) You can derive from a class.
But note that one has to be careful whether that class is indeed meant for inheritance.
For example: If you have a class with non virtual destructor then that class is not meant for inheritance. Just like all standard library container classes.

So in short, Just having a interface of class is enough for derivation but the implementation and design semantics of the class do play an important role.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM