What are some C++ related idioms, misconceptions, and gotchas that you\'ve learnt from experience?
An example:
class A
{
public:
char s[1024];
cha
One seldom used, but handy C++ idiom is the use of the ?: operator during the constructor chain.
class Sample
{
const char * ptr;
const bool freeable;
Sample(const char * optional):
ptr( optional ? optional : new char [32]),
freeable( optional ? false : true ) {}
~Sample( ) { if (freeable) delete[] ptr; }
}
C++ doesn't allow const values to be changed inside the body of the constructor, so this avoids const-casts.
If you have a class which does not have value semantics, make sure that all of the following constructs are explicitly declared in order to prevent headaches down the road.
In many cases you only need to declare a subset of these constructs. However it can get really tricky in some cases as to which are needed and which are not. It's much safer to declare all 3 private and be done with the matter.
It's also very helpful to add a comment to the top explaining that this is not a copy safe class.
This will save you time down the road.
Here is another one i caught some day:
char int2hex(int x) {
return "-0123456789abcdef"[(x >= 0 && x < 16) ? (x + 1) : 0];
}
it's just indexing the char array instead of doing a switch. If it's outside the range, it returns '-'.
Since we're all ignoring the OP and instead posting our favourite cool tricks...
Use boost (or tr1) shared_ptr to maintain a class invariant at runtime (kind of obvious, but I haven't seen anyone else do it):
#include <cassert>
#include <functional>
#include <stdexcept>
#include <boost/shared_ptr.hpp>
using namespace std;
using namespace boost;
class Foo
{
public:
Foo() : even(0)
{
// Check on start up...
Invariant();
}
void BrokenFunc()
{
// ...and on exit from public non-const member functions.
// Any more is wasteful.
shared_ptr<Foo> checker(this, mem_fun(&Foo::Invariant));
even += 1;
throw runtime_error("didn't expect this!");
even += 1;
}
private:
void Invariant() { assert(even % 2 == 0); }
int even;
};
Use boost::spirit::hold_any
(link) instead of boost::any
for performance code (while holding a large number of small objects). I saw a large difference in their performances.
I've liked this since the time i've discovered it in some code:
assert(condition || !"Something has gone wrong!");
or if you don't have a condition at hand, you can just do
assert(!"Something has gone wrong!");
The following is attributed to @Josh (see comments). It uses the comma operator instead:
assert(("Something has gone wrong!", condition));