Contact:
Thorsten Gunkel
63456 Hanau
Germany
Mail
Vote to help me to improve this page!
Did this page satisfy your expectations?
vote3 Yes
vote2 Partly
vote1 No
Short comment?
Do not change this:
Add your comment to the
guestbook.
Last modified: 18-05-2008 15.06
NO ePATENTS

C / C++

See also

Literature List

Author Title
Bjarne Stroustrup The C++ Programming Language 3. Edition
Ulrich Breymann C++ Eine Einführung
Namir Clement Shammas C++ für Dummies
09-12-2007 02.27

How programs are being startet


A short overview about ELF and how programs are started in Linux.
18-05-2008 15.06

Compiler Variables

Change C and C++ compiler:

export CC=gcc-3.2 CXX=g++-3.2
06-08-2005 13.09

Debug C / C++ Crashes:

$ ulimit -c unlimited
$ gcc -g PRG
$ g++ -g PRG
$ ./PRG
- CRASH -
$ gdb PRG core
run
bt
up
down
print $VAR
break foo.cpp:301
delete 1


DDD - Data Display Debugger

Find C / C++ Memoryleaks

valgrind
valgrind --leak-check=yes --show-reachable=yes ./MYPROGRAM

memprof
alleyoop

Runtime profiling

GNU gprof
g++ -g -pg foo.cpp -o foo.run
./run
gprof foo.run gmon.out | less
gprof foo.run gmon.out -f Foo::myfunction | less

doxygen

doxygen doxygen (x)emacs
C-c d f
C-c d ;
23-12-2006 12.47

File Structure

.h

#ifndef _myh1_h_
#define _myh1_h_

#include <iostream>

namespace my_program {
extern int global1;
}

#endif /* _myh1_h_ */

.cpp

#include <GL/glut.h>


#include "cg3_ex1.h"


using namespace std;


namespace my_program
{
int global1 = 5;
float global2 = 6.0;


/**
* comment here
*/
void foo()
{
}


}


int main(int argc, char **argv)
{
using namespace my_program;
return 0;
}

Macros

In C++ try to avoid them.
#define FOO blabla
#define BAR(a,b) 1: a 2: b
(no ; at the end of the line necessary, FOO and BAR are just replace everywhere).

Don't compile certain areas:
#define VERSION1
...
#ifdef VERSION1
...
#elseif
...
#endif

Don't forget parenthesis
#define SQUARE1(a) a*a
#define SQUARE2(a) (a)*(a)
SQUARE1(1+2) // 1+2*1+2
SQUARE2(1+2) // (1+2)*(1+2)
26-10-2006 06.14

Variables

Normal

int  x;  x=5;  cout << x; // 5

Reference

int& r=x;      cout << r; // 5

Pointer

int* y;  y=&x; cout << y; // 5 if x is still valid, trouble otherwise
int* y; y=new int; delete y;
int* z; z=y; cout << z // 5
x=*z; cout << x // 5

Memory

int * ptr2=(int*)malloc(155*sizeof(int));
for (int i=0; i<155; i++) {
std::cout << ptr2[i];
}

Size of the Variables

#include <limits>
#include <iostream>

int main()
{
using namespace std;
numeric_limits<int> INT;
...
cout << "INT Min: " << INT.min() << " Max: " << INT.max() << " EP: " << INT.epsilon() << endl;
...
}

int uint short ushort long ulong float double ldouble
min i486 -2147483648 +0 -32768 +0 -2147483648 +0 1.17549e-38 2.22507e-308 3.3621e-4932
min amd64 -9223372036854775808
max i486 +2147483647 +4294967295 +32767 +65535 +2147483647 +4294967295 3.40282e+38 1.79769e+308 1.18973e+4932
max amd64 +9223372036854775807 +18446744073709551615
epsilon i486 0 1.19209e-07 2.22045e-16 1.0842e-19
epsilon amd64
In C abfangen ob die Integer Grenzen überschritten wurden

const

Value of x can't be changed
const int               x=4;
Pointer points to a value which can't be changed
      int const *       z;
const int * z;
Const pointer, value can be changed
      int       * const z;
Pointer and value are const
      int const * const z;
const int * const z;
Methods which don't modify class variables should be declared const
class Foo {
public:
int getX() const {
return this->x;
}
}

mutable / const_cast

Sometime you might want to modify an unimportant class variable in a const method, e.g. you might want to count how often a get method was accessed:
class Foo {
unsigned int statistic_access_counter;
public:
int getX() const {
this->statistic_access_counter++; // Error!
return this->x;
}
}
This won't be allowed by your compiler
You can either use const_cast to get full write access:
class Foo {
unsigned int statistic_access_counter;
public:
int getX() const {
Foo * tmp=const_cast<Foo *>(this);
tmp->statistic_access_counter++;
return this->x;
}
}
or (which is the better solution) mark the unimportant variables which might to modified in const methods:
class Foo {
mutable unsigned int statistic_access_counter;
public:
int getX() const {
this->statistic_access_counter++;
return this->x;
}
}

Fields / Arrays

int * ptr2=(int*)malloc(155*sizeof(int));
for (int i=0; i<155; i++) {
std::cout << ptr2[i];
}
int  a[3]; // a[0], a[1], a[2]
int b[]= {10,11,42};
char c[]= {'a','z','m'};
int d[2]={10,11,42}; // Error!
int d[7]={10,11}; // a[2]==a[3]==...==a[6]==0
b={10,11,42}; // Error

c String Copy

Tricky example how to copy a 0 terminated c string.

mystringcopy(char * a, const char * b) {

// A
while(*b!=0) {
*a=*b;
a++;
b++;
}
*a=0;

// B
while( (*a++=*b++) != 0 );

// C
while( *a++=*b++ );

}
Variant B and C use the fact that a=b returns b.

Strings

char c[3];
c[0]='a';
c[1]='b';
c[2]=0;
char * c1=new char[3];
char * c2="ab";

Int to String

int i=1242;
int len=(int)floor(log(i)/log(10));
char c[16+l+1];
snprintf(c,sizeof(c),"This is my int: %d",i);
c[sizeof(c)-1]=0;

String to int

char c[5]="1242";
int i=atoi(c);
char *p, *s;
s = "20y";
int i2 = strtol(s,&p,0); // i2:20 p:y

string

string str2("abc");
C++ strings

Enumeration

enum           { FOO,   BAR   };
enum myenumtyp { FOO, BAR };
typedef enum { FOO, BAR } myenumtyp;
enum myenumtyp { FOO=0, BAR=1 };
Enumerations are often better than normal constants because the compiler can check if you didn't miss one in e.g., a switch statemant.
27-01-2007 06.37

Functions

Normal function which returns a value and copies the value of the parameter before using it:
int foo(int x) {
return x++;
}
This does the same as the previous example. However the parameter is a (read only) reference to the original variable. This is faster for large objects:
int foo(const int& x) {
return x++;
}
Here the parameter can be changed and all changes will persist when the function terminates:
void foo(int& x) {
x++;
}
Return by reference. Important: Store the result into a reference variable, otherwise you get a copy.
int & foo() {
return x;
}

int a=foo(); // :-(
int & b=foo(); // :-)

Pointers to Functions

First two normal functions:
int DoIt1  (float a, int b, int c)
{
return a+b+c;
}

int DoIt2 (float a, int b, int c)
{
return a*b*c;
}

class MyClass {
public:
int DoIt3(float a, int b, int c)
{
return a+b*c;
};
};
Define pointers for them:
int (         *foo)(float, int, int);
int (MyClass::*bar)(float, int, int)=&MyClass::DoIt3;
Assign the the pointers to the functions:
foo = DoIt1;
int result1 = foo(1.0, 2, 3);
int result2 = (*foo)(1.0, 2, 3);

foo = DoIt2;
int result3 = foo(1.0, 2, 3);

MyClass * f;
int result4 = f->DoIt3(1.0, 2, 3);
int result5 = (f->*bar)(1.0, 2, 3);
A pointer as a parameter:
void myfunc(int (*foo)(float, int, int))
{
int result = foo(1.0, 2, 3);
}

myfunc(&DoIt1);
myfunc(&DoIt2);

Parameters

void foo(bool a, bool b=false);
The second parameter is optional, default is false
void foo(bool a ...);
As many bool parameters as you need (at least one), see <cstdarg> how to get the parameters.

02-11-2006 21.53

Classes and Objects

class MyClass : public MyParentClass
{
public:
MyClass();
MyClass(int x);
int my_method() const;
static int getTime();

protected:
int my_var;

private:
};

MyClass::MyClass() {
..
}

int MyClass::MyClass(int x) : MyParentClass(59)
{
...
}

int MyClass::my_method() const {
...
}
int MyClass::getTime() {
...
//in java super()
this is super() for c++
MyParentClass::getTime();
...
}

MyClass   x(5);
MyClass * x=new MyClass(5);

Static methods and static variables

Note that you need exactly one additional definition of the static variables outside the class.
If you implement a static method do not repeat the keyword static.
class MyOtherClass {

public:

MyOtherClass() {
z=0;
}

static int foo() {
return ( MyOtherClass::x + MyOtherClass::y );
}

int bar() {
return ( MyOtherClass::x + MyOtherClass::y + this->z );
}

protected:
static int y;
static int x;
int z;
};

// !!!
int MyOtherClass::x=0;
int MyOtherClass::y=0;
// !!!

int main() {
...
}

Virtuell Methods

If you modify non-virtual methods in derivated classes you might be surprised that the method from the father class might be called. Evil if the the destructor method is one of these methods.
#include <iostream>
using namespace std;

class A {
public:
int foo() {
return 1;
}

virtual int bar() {
return 1;
}

//~A() { <------ Don't!
virtual ~A() {
//...
}
};

class B : public A {
public:
int foo() {
return 2;
}

virtual int bar() {
return 2;
}

//~B() {
virtual ~B() {
//..
}
};

int main() {
A a; B b; A * x; x=&b;
cout << a.foo() << a.bar() << endl; // 11
cout << b.foo() << b.bar() << endl; // 22
cout << x->foo() << x->bar() << endl; // 12
return 0;
}

Access Control

public:Everyone
protected:Only objects of this class + descendants
private:Only class
Try to make class variables private, methoden protected, avoid public.

Namespace

Group different parts of the program in its own namespace.
namespace Foo {
double x;
double getX();
}

namespace Foo_1 {...};
namespace Foo_2 {...};

namespace MyFoo=Foo_2;
So you can even give a namespace a different name. Easy to switch between different namespaces.

How to access elements of different namespaces
int y=Foo::x;

using Foo::getX;
using Foo;
You can also use using to make the protected method of you parent class a public method of yourself
class A {
protected:
double getX();
};

class B : public A {
public:
using A::getX;
};

Copy Constructor

Foo a;
Foo b=a;
ruft den Copy Konstruktor auf:
Foo::Foo(const Foo& a);
If your object has pointers to memory which has to be freed in the destructor this may cause problems:
Foo a;
Foo b=a;
Foo c;
The destructor is only called for a and c, for b the copy constructor is called instead.
At the end the destructor for all of the is called and you may free memory twice.

If there is a matching constructor you can initialise an object via an assignment:
class complex {
public:
complex(double r, double i) {this->re=r; this->im=i;}
complex(double r) {this->re=r; this->im=0;}
private:
double re,im;
}

complex a=complex(2.3);
complex b=2.3;

Inheritance

Multiple Inheritance

class A                      {};
class B : public A {};
class C : public A {};
class D : public B, public C {};

A A
| |
B C
\ /
D
Now there are two different A objects. Better declare a virtual inheritance to A:
class A                      {};
class B : public virtual A {};
class C : public virtual A {};
class D : public B, public C {};

A
/ \
B C
\ /
D

Cast

FOO a;
BAR b=(BAR)a;

FOO * c;
BAR * d=(BAR *)c;

dynamic_cast / static_cast

Assume we have the following hierarchy
class A                      {};
class B {};
class C : public A {};
class D : public B {};
class E : public C, public D {};

A B
| |
C D
\ /
E
And want to cast an object of the type A* to one of the type B*.
You can do that manually:
A * a;
C * c=(C*) a;
E * e=(E*)c;
D * d=e;
B * b=d;
Or with a dynamic_cast
B * b=dynamic_cast<B*>a;
This will fail of A has no virtual method with this error:
error: cannot dynamic_cast `a' (of type `class A*') to type `class B* ' (source type is not polymorphic)
static_cast is a bit faster, but has no checks if you're doing something reasonable. Avoid it.

typeid

Foo a;
Bar b;
if (typeid(a)==typeid(FOO)) ...
if (typeid(a)==typeid(BAR)) ...
if (typeid(b)==typeid(FOO)) ...
if (typeid(b)==typeid(BAR)) ...
28-10-2006 20.48

Exceptions

try {
...
throw(5);
...
throw(5.0);
}
// default catch, catch all
catch(int a)
{
}
catch(float b)
{
}
catch(...)
{
}
If possible list all exceptions you will throw:
void foo() throw();
void foo() throw(X,Y);
If another is thrown unexpected will be called.

auto_ptr

Problem:
foo() {
...
fopen(FILE);
...
if (...) throw error1;
...
fclose(FILE);
...
}
If an exception is thrown the will needs to be closed. Complicate to not miss any case. Tricky solution: Write a class which will open the file in its constructor and closes the file in the destructor:
class X {
public:
X() { fopen(FILE); };
~X() { fclose(FILE); };
}
Now you can rewrite the example like this:
foo() {
...
X x;
...
if(...) throw error1;
...
}
Now the file will be closed whenever the object leave the scope (which will also happen when the exception is thrown).
The is already a generic object for this available: auto_ptr from <memory>.

Exception is not only for Errors

Stack<int> data;

try
{
for(;;) { data.pop(); }
}
catch(data::Empty)
{
...
}
Instead to check in the for header when to stop just catch the exception. (Too) Tricky, better avoid it.

Assertions

//#define NDEBUG
#include <cassert>
assert(a>0 && b<0);
26-10-2006 05.49

Templates

Classtemplates

template <class Pairtype>
class Pair
{

template class Pair<int>;
template class Pair<double>;

public:
Pair();
Pair(Pairtype left, Pairtype right);
Pairtype get_left();
void set_left(Pairtype left);

protected:
Pairtype left;
Pairtype right;
};
}
template <class Pairtype>
Pair<Pairtype>::Pair(Pairtype left, Pairtype right)
{
this->left=left;
this->right=right;
}

template <class Pairtype>
Pairtype Pair<Pairtype>::get_left()
{
return left;
}

template <class Pairtype>
void Pair<Pairtype>::set_left(Pairtype left)
{
this->left=left;
}
Pairtype<int> foo;
07-09-2006 14.27

Singleton

class tg {
public:
static tg& get_instance(void) {
return tg::my_instance;
}
private:
static tg my_instance;
tg() {

}

tg(const tg&);

tg& operator=(tg&);
};

tg tg::my_instance;

int main(int argc, char **argv)
{
tg& a = tg::get_instance();
}
06-08-2005 13.09

Operator

class MyClass {
public:
...
MyClass & operator+=(const MyClass & other);
}

friend bool operator< (const MyClass& a, const MyClass& b) {
return a.foo<b.foo;
}

std::ostream& operator<< (std::ostream& os, const MyClass& a) {
os << "Foo: " << a.foo << " Bar: " << a.bar << std::endl;
return os;
}

Increment / Decrement Operator

// ++i
MyInt MyInt::operator++() {
value+=1;
return value;
}

// i++
MyInt MyInt::operator++(int) {
MyInt rescue=value;
value+=1;
return rescue;
}
26-10-2006 06.11

Iterators

vector <ContainerType>                           a;
vector <ContainerType>::iterator iter_a;
vector <ContainerType>::const_iterator constiter_b;
vector <ContainerType> c;
vector <ContainerType>::reverse_iterator inter_r;

iter_b=c.end();
iter_a=c.begin();
(*iter_a)=c.at(0);
while (iter_a!=c.end())
{
cout << *iter_a;
iter_a++;
}

if (c.end()!=c.begin()) {
iter_a=c.end();
do {
iter_a--;
cout << *iter_a << endl;
} while (iter_a!=c.begin());
}

for (iter_r=c.rbegin(); iter_r!=c.rend(); iter_r++) {
cout << *iter_r << endl;
}

for(iter_a=c.begin(),x=0;
iter_a!=c.end() && x<100;
iter_a++, x++
) {}

back_insert_iterator

If you like to insert something in a container you need a reasonable iterator.
b.end() points behind the end of the container, b.begin() would overwrite elements.
Solution: back_insert_iterator
#include <vector>
#include <list>
#include <iostream>

using namespace std;
int main() {

vector<int> a;
vector<int> b;

a.push_back(1);
a.push_back(2);
a.push_back(3);
copy(a.begin(), a.end(), back_insert_iterator<vector< int > >(b));

// 1
// 2
// 3
for(vector<int>::const_iterator i=b.begin(); i!=b.end(); i++)
cout << *i << endl;
cout << endl;

list<int> myList;
back_insert_iterator< list< int > > myListIteratorBack(myList);
front_insert_iterator< list< int > > myListIteratorFront(myList);

myListIteratorBack=4;
myListIteratorBack=5;
myListIteratorFront=6;

// 6
// 4
// 5
for(list<int>::const_iterator i=myList.begin(); i!=myList.end(); i++)
cout << *i << endl;
cout << endl;

}

Functions to Walk Through a stl Container

Try not to iterate through the container yourself
vector<int> a;
for(vector<int>::iterator i=a.begin(); i!=a.end(); i++) foo(*i);
instead use stl functions for that:
sort(a.begin(), a.end());
for_each(a.begin(), a.end(), foo);
The last one won't work with methods (only function). If you have a class:
class X {
public:
void draw();
}
and want to call a method of each element use a function for that:
vector<X *> data;

void foo(X * x) {
x->draw();
}

for_each(data.begin(), data.end(), foo);
There is already a function called mem_fun for this:
for_each(data.begin(), data.end(), mem_fun(&X::draw));
List with useful functions:

Sort with a Functor

functor
class mycomp {
public:
bool operator()(double x, double y) { return fabs(x) < fabs(y); }
};

vector<double> data;
sort(data.begin(), data.end(), mycomp());
30-10-2006 21.48

Control Flow

continue

Skips the rest of the current loop run and starts the next one
for (int i=0; i<5; i++) {
std::cout << "\n";
std::cout << i << " ";
if (i==2) continue;
std::cout << i;
}
Output
0 0
1 1
2
3 3
4 4

break

Skips the whole loop
for (int i=0; i<5; i++) {
std::cout << "\n";
std::cout << i << " ";
if (i==2) break;
std::cout << i;
}
Output
0 0
1 1
2
Beside continue and break there is also goto! ;-)
goto foo;
...
foo:
...

Conditional Expressions

if  (a<=b)   max=a; else max=b;
max=(a<=b) ? a : b;

Header

cout#include <iostream>
std::cout << std::setw(8) << foo << std::endl;#include <iomanip>
fabs(int)#include <cstdlib>
fabs(float)#include <cmath>
29-10-2006 02.17

Use two different C++ Compiler Versions for one Project


Assume you have the following small project:
new.cpp
#include "old.h"

class newClass
{
public:
int newClassMethod(int x) {
return proxy(x);
}

};

int main(int argc, char **argv) {
newClass newObject;
return newObject.newClassMethod(5);
}
old.h
int proxy(int x);
old.cpp
#include "old.h"

class oldClass
{
public:
int myold(int x) {
return 25;
}
};

int proxy(int x) {
oldClass oldObject;
return oldObject.myold(x);
}

In new.cpp there is an object of the newClass class which uses code from the file old.cpp. This project should compile without problems:
g++-2.95 -c old.cpp   -o old.o
g++-2.95 -c new.cpp -o new.o
g++-2.95 old.o new.o -o myproject

Things get interesting if you have to compile old.cpp with g++-2.95 (e.g. because you don't have access to the sources of old.o to recompile it) and want to compile the rest with a newer compiler
g++-2.95 -c old.cpp   -o old.o
g++-3.3 -c new.cpp -o new.o
g++-3.3 old.o new.o -o myproject

This will fail
new.o(.gnu.linkonce.t._ZN8newClass14newClassMethodEi+0xd): In function `newClass::newClassMethod(int)':
: undefined reference to `proxy(int)'
collect2: ld returned 1 exit status
because the ABI between gcc-3.2 and the ABI of previous versions differ. However there is a way to circumvent this. Just offer in one of the files, which also has been compiled with an old version of the compiler, a C function which can be uses as a interface between both worlds. This works because the ABI only changed for C++ code and not for C code. Everything we have to do in our example is to declare this function as a C function:
old.h
extern "C"
{
int proxy(int x);
}
Now it can be used as an interface between both worlds.

However there are still problems if the new and the old files like to use for example the stl libs. This is how you can fix it:
Example project: newClass.cpp, newClass.h, new.cpp , oldClass.cpp , oldClass.h, old.cpp, old.h.

First compile all the files with their matching compiler
g++-2.95 -c old.cpp      -o old.o
g++-2.95 -c oldClass.cpp -o oldClass.o
g++-3.3 -c new.cpp -o new.o
g++-3.3 -c newClass.cpp -o newClass.o
Now combine all old .o files to one static file .o. This will show you how to do it:
g++-2.95 -v -static -r -o allOldStuff.o   old.o oldClass.o
Be careful not to include the same file twice in the next step so remove some of the .o files from the command line until the next steps works without errors about duplicates. It may look like this:
/usr/lib/gcc-lib/i386-linux/2.95.4/collect2 -m elf_i386 -static -o allOldStuff.o -r -L/usr/lib/gcc-lib/i386-linux/2.95.4 old.o oldClass.o -lstdc++ -lm -lgcc -lc -lgcc /usr/lib/gcc-lib/i386-linux/2.95.4/crtend.o /usr/lib/crtn.o
Everything that is left is to combine all new .o files against the .o you created from all the old files:
g++ -o MyProgram  new.o newClass.o allOldStuff.o

Done :-)

Sadly it looks there are run-time problems with this solution.

06-09-2006 00.02
Thanks to Richard Eckart for all the hints.
18-05-2008 15.06
Powered by PHP Created with Xemacs Valid XHTML 1.0! Valid CSS!