Question about best practices and Macros from the book 'C++ Coding Standards'
From Herb Sutter and Andrei Alexandrescu's 'C++ Coding Standards', Item 16: Avoid Macros under Exceptions for this guideline they wrote:
For conditional compilation (e.g., system-dependent parts), avoid littering your code with #ifdefs. Instead, prefer to organize code such that the use of macros drives alternative implementations of one common interface, and then use the interface throughout.
I'm having trou开发者_如何学Cble understanding exactly what they mean by this. How can you drive alternate implementations without the use of #ifdef conditional compile macro directives? Can someone provide an example to help illustrate what's being proposed by the above paragraph?
Thanks
What they mean is that you should abstract your code from the system-dependent part through the use of abstract base classes and use condition compilation only at the point of instantiation.
class SystemAgnosticInterface
{
public:
virtual ~SystemAgnosticInterface() {}
virtual void doStuff() = 0;
};
You could then for example have a Windows and a Linux specific implementations of the interface (each of which you will only be included in the compilation for its associated platform), use such as :
SystemAgnosticInterface *createFoo()
{
#ifdef _WIN32
return new WindowsImplementation;
#else
return new LinuxImplementation;
#endif
}
int main()
{
SystemAgnosticInterface *foo = createFoo();
foo->doStuff(); // No conditional compilation here
delete foo;
}
This is obviously an over-simplified code sample, but I hope you'll understand the point : it's not about avoiding #ifdef
completely, just that they should not clutter every part of your code.
For non-member functions:
//implementation!
#ifdef _WIN32
void EatWindow(Food &) {}
void DrinkWindow(Beverage &) {}
void SleepWindow(Bed &) {}
#else
void EatLinux(Food &) {}
void DrinkLinux(Beverage &) {}
void SleepLinux(Bed &) {}
#endif
//interface
#ifdef _WIN32
#define Eat(food) EatWindow(food)
#define Drink(beverage) DrinkWindow(beverage)
#define Sleep(bed) SleepWindow(bed)
#else
#define Eat(food) EatLinux(food)
#define Drink(beverage) DrinkLinux(beverage)
#define Sleep(bed) SleepLinux(bed)
#endif
Use the interfaces Eat()
, Drink()
and Sleep()
throughout your program, be it windows or linux. No conditional check anywhere else!
精彩评论