Should MACROs be avoided when making a library - c++

The library offers a class to be derived from with the derived class as a template argument.
Example:
class userclass : public lib::superclass<userclass>
{}
As you can see its quite a lot to type. And the "userclass" should always derive as public for it to work correctly. So i came up with two MACROs looking like this:
#define SUPER(x) public lib::superclass<x>
#define SUPERCLASS(x) class x : public lib::superclass<x>
The user can now type either of.
class userclass : SUPER(userclass)
{}
SUPERCLASS(userclass)
{}
But the main problem is that the macros SUPER and SUPERCLASS exist in the users global namespace as quick as the header is included.
Can/should i:
Have a way of preserving the namespace requirement but still defaulting to public derives?
Use the macros as they are.
Simply require the user to write out the full "public lib::superclass".
I'm using vs 11 and the library is targeted against windows developers.

The first rule of using macros is "Don't, if there's any other solution". In this case, there is another solution, so get rid of them.
Secondly, your macros do way more harm than good, because people have no idea what they expand to by just reading it, whereas the full definition does. Seriously, you're saving a truly minute number of characters for a truly hideous cost in readability. It's far superior to simply write out the inheritance.

That really isn't a lot to type. I've seen a lot longer lines that shouldn't be shortened. Hiding it with a macro just obfuscates your code. If I take a quick look at your SUPERCLASS(userclass) {}, I can pretty much guess that it's a class (I don't like to use a library based on guesses) but I don't know if it or its parent is called userclass (or neither) or what kind of inheritance it's using. It means you have to document it and you force people to look it up when they need it.
So the correct answer is option 3 - don't use macros.
If you really really really need to use a macro in your library, give it a library specific prefix. That's as close as you'll get to a namespaced macro.

I vote for 3. Simply require the user to write out the full "public lib::superclass".
Macros in libraries may be useful if:
there is really a lot to write,
something has to be written several times
or you want to hide an ugly implementation detail and the language doesn't allow you to do otherwise.
But in your case:
not so much to write,
yes, you have to put the class name twice,
you do not want to hide the fact that you are subclassing, or even that you are writing a class!
I don't think that the duplication of the class name - the one positive point - is worth it. Particularly because you will hide the class keyword and cause quite some confusion on the reader.
Anyway, if a library uses macros it is customary to put the library name in front of all macros:
#define MY_FANCY_LIBRARY_NAME_SUPER(x) public lib::superclass<x>
But now you are not saving so much typing...
PS: Remember the golden rule of programming:
Code is written once but read forever, thus it should be easy to read, more than easy to write.

Related

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 y.o. 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.

I've done a shady thing

Are (seemingly) shady things ever acceptable for practical reasons?
First, a bit of background on my code. I'm writing the graphics module of my 2D game. My module contains more than two classes, but I'll only mention two in here: Font and GraphicsRenderer.
Font provides an interface through which to load (and release) files and nothing much more. In my Font header I don't want any implementation details to leak, and that includes the data types of the third-party library I'm using. The way I prevent the third-party lib from being visible in the header is through an incomplete type (I understand this is standard practice):
class Font
{
private:
struct FontData;
boost::shared_ptr<FontData> data_;
};
GraphicsRenderer is the (read: singleton) device that initializes and finalizes the third-party graphics library and also is used to render graphical objects (such as Fonts, Images, etc). The reason it's a singleton is because, as I've said, the class initializes the third-party library automatically; it does this when the singleton object is created and exits the library when the singleton is destroyed.
Anyway, in order for GR to be able to render Font it must obviously have access to its FontData object. One option would be to have a public getter, but that would expose the implementation of Font (no other class other than Font and GR should care about FontData). Instead I considered it's better to make GR a friend of Font.
Note: Until now I've done two things that some may consider shady (singleton and friend), but these are not the things I want to ask you about. Nevertheless, if you think my rationale for making GR a singleton and a friend of Font is wrong please do criticize me and maybe offer better solutions.
The shady thing. So GR has access to Font::data_ though friendship, but how does it know exactly what a FontData is (since it's not defined in the header, it's an incomplete type)? I'll just show the code and the comment that includes the rationale...
// =============================================================================
// graphics/font.cpp
// -----------------------------------------------------------------------------
struct Font::FontData
: public sf::Font
{
// Just a synonym of sf::Font
};
// A redefinition of FontData exists in GraphicsRenderer::printText(),
// which will have to be modified as well if this definition is modified.
// (The redefinition is called FontDataSurogate.)
// Why not have FontData defined only once in a separate header:
// If the definition of FontData changes, most likely printText() text will
// have to be altered also regardless. Considering that and also that FontData
// has (and should have) a very simple definition, a separate header was
// considered too much of an overhead and of little practical advantage.
// =============================================================================
// graphics/graphics_renderer.cpp
// -----------------------------------------------------------------------------
void GraphicsRenderer::printText(const Font& fnt /* ... */)
{
struct FontDataSurogate
: public sf::Font {
};
FontDataSurogate* suro = (FontDataSurogate*)fnt.data_.get();
sf::Font& font = (sf::Font)(*suro);
// ...
}
So that's the shady thing I'm trying to do. Basically what I want is a review of my rationale, so please tell me if you think I've done something horrendous or if not confirm my rationale so I can be a bit surer I'm doing the right thing. :) (This is my biggest project yet and I'm only at the beginning so I'm kinda feeling things in the dark atm.)
In general, if something looks sketchy, I've found that it's often worth going back a few times and trying to figure out exactly why that's necessary. In most cases, some kind of fix pops up (maybe not as "nice", but not relying on any kind of trick).
Now, the first issue I see in your example is this bit of code:
struct FontDataSurogate
: public sf::Font {
};
occurs twice, in different files (neither being a header). That may come back and be a bother when you change one but not the other in the future, and making sure both are identical will very likely be a pain.
To solve that, I would suggest putting the definition to FontDataSurogate and the appropriate includes (whatever library/header defines sf::Font) in a separate header. From the two files that need to use FontDataSurogate, include that definition header (not from any other code files or headers, just those two).
If you have a main class declaration header for your library, place the forward declaration for the class there, and use pointers in your objects and parameters (regular pointers or shared pointers).
You can then use friend or add a get method to retrieve the data, but by moving the class definition to its own header, you've created a single copy of that code and have a single object/file that's interfacing with the other library.
Edit:
You commented on the question while I was writing this, so I'll add on a reply to your comment.
"Too much overhead" - more to document, one more thing to include, the complexity of the code grows, etc.
Not so. You will have one copy of the code, compared to the two that must remain identical now. The code exists either way, so it needs documented, but your complexity and particularly maintenance is simplified. You do gain two #include statements, but is that such a high cost?
"Little practical advantage" - printText() would have to be modified every time FontData is modified regardless of whether or not it's defined in a separate header or not.
The advantage is less duplicate code, making it easier to maintain for you (and others). Modifying the function when the input data changes is not surprising or unusual really. Moving it to another header doesn't cost you anything but the mentioned includes.
friend is fine, and encouraged. See C++ FAQ Lite's rationale for more info: Do friends violate encapsulation?
This line is indeed horrendous, as it invokes undefined behavior: FontDataSurogate* suro = (FontDataSurogate*)fnt.data_.get();
You forward declare the existence of the FontData struct, and then go on to fully declare it in two locations: Font, and GraphicsRenderer. Ew. Now you have to manually keep these exactly binary compatible.
I'm sure it works, but you're right, it is kindof shady. But whenever we say such-and-such is eeevil, we mean to avoid a certain practice, with the caveat that sometimes it can be useful. That being said, I don't think this is one of those times.
One technique is to invert your handling. Instead of putting all of the logic inside GraphicsRenderer, put some of it inside Font. Like so:
class Font
{
public:
void do_something_with_fontdata(GraphicsRenderer& gr);
private:
struct FontData;
boost::shared_ptr<FontData> data_;
};
void GraphicsRenderer::printText(const Font& fnt /* ... */)
{
fnt.do_something_with_fontdata(*this);
}
This way, the Font details are kept within the Font class, and even GraphicsRenderer doesn't need to know the specifics of the implementation. This solves the friend issue too (although I don't think friend is all that bad to use).
Depending on how your code is laid out, and what it's doing, attempting to invert it like this may be quite difficult. If that is the case, simply move the real declaration of FontData to its own header file, and use it in both Font and GraphicsRenderer.
You've spent a lot more effort asking this question then you've supposedly saved by duplicating that code.
You state three reasons you didn't want to add the file:
Extra include
Extra Documentation
Extra Complexity
But I would have to say that 2 and 3 are increased by duplicating that code. Now you document what its doing in the original place and what the fried monkey its doing defined again in another random place in the code base. And duplicating code can only increase the complexity of a project.
The only thing you are saving is an include file. But files are cheap. You should not be afraid of creating them. There is almost zero cost (or at least there should be) to add a new header file.
The advantages of doing this properly:
The compiler doesn't have to make the definition you give compatible
Someday, somebody is going to modify the FontData class without modifying PrintText(), maybe they should modify PrintText(), but they either haven't done it yet or don't know that they need to. Or perhaps in a way that simply hasn't occoured to additional data on FontData make sense. Regardless, the different pieces of code will operate on different assumptions and will explode in a very hard to trace bug.

OOP vs macro problem

I came across this problem via a colleague today. He had a design for a front end system which goes like this:
class LWindow
{
//Interface for common methods to Windows
};
class LListBox : public LWindow
{
//Do not override methods in LWindow.
//Interface for List specific stuff
}
class LComboBox : public LWindow{} //So on
The Window system should work on multiple platforms. Suppose for the moment we target Windows and Linux. For Windows we have an implementation for the interface in LWindow. And we have multiple implementations for all the LListBoxes, LComboBoxes, etc. My reaction was to pass an LWindow*(Implementation object) to the base LWindow class so it can do this:
void LWindow::Move(int x, int y)
{
p_Impl->Move(x, y); //Impl is an LWindow*
}
And, do the same thing for implementation of LListBox and so on
The solution originally given was much different. It boiled down to this:
#define WindowsCommonImpl {//Set of overrides for LWindow methods}
class WinListBox : public LListBox
{
WindowsCommonImpl //The overrides for methods in LWindow will get pasted here.
//LListBox overrides
}
//So on
Now, having read all about macros being evil and good design practices, I immediately was against this scheme. After all, it is code duplication in disguise. But I couldn't convince my colleague of that. And I was surprised that that was the case. So, I pose this question to you. What are the possible problems of the latter method? I'd like practical answers please. I need to convince someone who is very practical (and used to doing this sort of stuff. He mentioned that there's lots of macros in MFC!) that this is bad (and myself). Not teach him aesthetics. Further, is there anything wrong with what I proposed? If so, how do I improve it? Thanks.
EDIT: Please give me some reasons so I can feel good about myself supporting oop :(
Going for bounty. Please ask if you need any clarifications. I want to know arguments for and vs OOP against the macro :)
Your colleague is probably thinking of the MFC message map macros; these are used in important-looking places in every MFC derived class, so I can see where your colleague is coming from. However these are not for implementing interfaces, but rather for details with interacting with the rest of the Windows OS.
Specifically, these macros implement part of Windows' message pump system, where "messages" representing requests for MFC classes to do stuff gets directed to the correct handler functions (e.g. mapping the messages to the handlers). If you have access to visual studio, you'll see that these macros wrap the message map entries in a somewhat-complicated array of structs (that the calling OS code knows how to read), and provide functions to access this map.
As MFC users, the macro system makes this look clean to us. But this works mostly because underlying Windows API is well-specified and won't change much, and most of the macro code is generated by the IDE to avoid typos. If you need to implement something that involves messy declarations then macros might make sense, but so far this doesn't seem to be the case.
Practical concerns that your colleague may be interested in:
duplicated macro calls. Looks like you're going to need to copy the line "WindowsCommonImpl" into each class declaration - assuming the macro expands to some inline functions. If they're only declarations and the implementations go in a separate macro, you'll need to do this in every .cpp file too - and change the class name passed into the macro every time.
longer recompile time. For your solution, if you change something in the LWindow implementation, you probably only need to recompile LWindow.cpp. If you change something in the macro, everything that includes the macro header file needs to be recompiled, which is probably your whole project.
harder to debug. If the error has to do with the logic within the macro, the debugger will probably break to the caller, where you don't see the error right away. You may not even think to check the macro definition because you thought you knew exactly what it did.
So basically your LWindow solution is a better solution, to minimize headaches down the road.
Does'nt answer your question directly may be, but can't help from telling you to Read up on the Bridge Design pattern in GOF. It's meant exactly for that.
Decouple an abstraction from its
implementation so that the two can
vary independently.
From what I can understand, you are already on the right path, other than the MACRO stuff.
My reaction was to pass an
LWindow*(Implementation object) to the
base LWindow class so it can do this:
LListBox and LComboBox should receive an instance of WindowsCommonImpl.
In the first solution, inheritance is used so that LListBox and LComboBox can use some common methods. However, inheritance is not meant for this.
I would agree with you. Solution with WindowsCommonImpl macro is really bad. It is error-prone, hard to extend and very hard to debug. MFC is a good example of how you should not design your windows library. If it looks like MFC, you are really on a wrong way.
So, your solution obviously better than macro-based one. Anyway, I wouldn't agree it is good enough. The most significant drawback to me is that you mix interface and implementation. Most practical value of separating interface and implementation is ability to easily write mock objects for testing purposes.
Anyway, it seems the problem you are trying to solve is how to combine interface inheritance with implementation inheritance in C++. I would suggest using template class for window implementation.
// Window interface
class LWindow
{
};
// ListBox interface (inherits Window interface)
class LListBox : public LWindow
{
};
// Window implementation template
template<class Interface>
class WindowImpl : public Interface
{
};
// Window implementation
typedef WindowImpl<LWindow> Window;
// ListBox implementation
// (inherits both Window implementation and Window interface)
class ListBox : public WindowImpl<LListBox>
{
};
As I remember WTL windows library is based on the similar pattern of combining interfaces and implementations. I hope it helps.
Oh man this is confusing.
OK, so L*** is a hierarchy of interfaces, that's fine. Now what are you using the p_Impl for, if you have an interface, why would you include implementation in it?
The macro stuff is of course ugly, plus it's usually impossible to do. The whole point is that you will have different implementations, if you don't, then why create several classes in the first place?
OP seems confused. Here' what to do, it is very complex but it works.
Rule 1: Design the abstractions. If you have an "is-A" relation you must use public virtual inheritance.
struct Window { .. };
struct ListBox : virtual Window { .. };
Rule 2: Make implementations, if you're implementing an abstraction you must use virtual inheritance. You are free to use inheritance to save on duplication.
class WindowImpl : virtual Window { .. };
class BasicListBoxImpl : virtual ListBox, public WindowImpl { .. };
class FancyListBoxImpl : public BasicListBoxImpl { };
Therefore you should read "virtual" to mean "isa" and other inheritance is just saving on rewriting methods.
Rule3: Try to make sure there is only one useful function in a concrete type: the constructor. This is sometimes hard, you may need some default and some set methods to fiddle things. Once the object is set up cast away the implementation. Ideally you'd do this on construction:
ListBox *p = new FancyListBoxImpl (.....);
Notes: you are not going to call any abstract methods directly on or in an implementation so private inheritance of abstract base is just fine. Your task is exclusively to define these methods, not to use them: that's for the clients of the abstractions only. Implementations of virtual methods from the bases also might just as well be private for the same reason. Inheritance for reuse will probably be public since you might want to use these methods in the derived class or from outside of it after construction to configure your object before casting away the implementation details.
Rule 4: There is a standard implementation for many abstractions, known as delegation which is one you were talking about:
struct Abstract { virtual void method()=0; };
struct AbstractImpl_Delegate: virtual Abstract {
Abstract *p;
AbstractImpl_Delegate (Abstract *q) : p(q) {}
void method () { p->method(); }
};
This is a cute implementation since it doesn't require you to know anything about the abstraction or how to implement it... :)
I found that
Using
the preprocessor #define directive to
define constants is not as precise.
[src]
Macros are apparently not as precise, I did not even know that...
The classic hidden dangers of the preprocessor like:
#define PI_PLUS_ONE (3.14 + 1)`
By doing so, you avoid the possibility
that an order of operations issue will
destroy the meaning of your constant:
x = PI_PLUS_ONE * 5;`
Without
parentheses, the above would be
converted to
x = 3.14 + 1 * 5;
[src]

Private class functions vs Functions in unnamed namespace

I've found myself that I tend not to have private class functions. If possible, all candidates to private class function rather I put in to unnamed namespace and pass all necessary information as function parameters. I don't have a sound explanation why I'm doing that but at least it looks more naturally to me. As a consequence I need to expose less internal details in the header file.
What is your opinion - is it correct practice?
In the semi large projects where I usually work (more than 2 million lines of code) I would ban private class functions if I could. The reason being that a private class function is private but yet it's visible in the header file. This means if I change the signature (or the comment) in anyway I'm rewarded sometimes with a full recompile which costs several minutes (or hours depending on the project).
Just say no to that and hide what's private in the cpp file.
If I would start fresh on a large c++ project I would enforce PIMPL Idiom: http://c2.com/cgi/wiki?PimplIdiom to move even more private details into the cpp file.
I've done this in the past, and it has always ended badly. You cannot pass class objects to the functions, as they need to access the private members, presumably by reference (or you end up with convoluted parameter lists) so you cannot call public class methods. And you can't call virtual functions, for the same reason. I strongly believe (based on experience) that this is A Bad Idea.
Bottom line: This sounds like the kind of idea that might work where the implementation "module" has some special access to the class, but this is not the case in C++.
It basically comes down to a question of whether the function in question really makes sense as part of the class. If your only intent is to keep details of the class out of the header, I'd consider using the pimpl idiom instead.
I think this is a good practice. It often has the benefit of hiding auxiallary structures and data types as well, which reduces the frequency and size of rebuilds. It also makes the functions easier to split out into another module if it turns out that they're useful elsewhere.

naming convention for public and private variable?

Is it wrong to use m_varname as public and the same class with _variable as private
Some concerns:
Why do you have public variables?
Identifiers starting with _ and __ are reserved for system libraries. In practice this doesn't matter very often, but it's nice to be aware.
With those things said, there's nothing wrong with creating a naming convention, regardless of how it looks. Just be consistent.
The same goes for C++ and for Java: you do not need any hungarian notation nor any prefixes/suffixes. You got keyword "this"!
class MyClass {
private:
int value;
public:
MyClass(int value) {
this->value = value;
}
}
Of course in this simple example you can (should!) use constructor initialization list ;)
So, instead using any awkward notations just employ language's possibilities. When you know the name of your member variable - you know that it is perfect. Why would you obfuscate it with "_"?
As for using the same names for public and private members: this absolutely wrong thinking! Why would one need two things to represent the same in the same class? Make it private, name it perfectly and give getters and setters public.
You should not use names that begin with an underscore or contain a double underscore. Those names are reserved for the compiler and implementation. Besides that restriction, you can use any naming convention you and your team likes. Personally, I hate any form of "Hungarian" notation and dislike the m_something notation as well. It really bothers me that if I need to change the type of a variable I need to go update its name everywhere where it occurs. That's a maintenance headache.
Everyone has his/her own preferences as far as naming conventions are concerned. I'd say more people would agree on not having any public variables in a class.
Assuming that you're working with C++, the my answer is NO. It's perfectly reasonable, but you'll should really stick to that convention.
However, statically typed languages such as C# assume such naming conventions to be somewhat redundant.
Personally I think it's ugly, but it's not apparent where a variable comes from in C++ as such the sugaring might help.
There are many C++ conventions out there. The key is to find one and/or adapt one. Stick with it, and be consistent. If you are working somewhere, try to get down as many of the conventions laid out. There's so many ones out there, and each one has good arguments, but they can contradict each-other (Joint Strike Fighter, Bell Labs, Mozilla, and so forth)
If there are different conventions between different parts of the project, at least make each file consistent within itself, and the .cpp and .h files should be consistent with each-other.
I find it better to be able to understand code written by different conventions so that you can easily adapt to a new working environment faster