Bitwise operators perform simple logic:
OR: If either or both bits is 1, result is 1. Otherwise result is zero:
1 2 3 4

0  0 == 0
0  1 == 1
1  0 == 1
1  1 == 1
 
AND: If both bits are 1, result is 1. Otherwise result is zero:
1 2 3 4

0 & 0 == 0
0 & 1 == 0
1 & 0 == 0
1 & 1 == 1
 
XOR: If either (but not both) bits are 1, result is 1. Otherwise (both bits zero, or both bits 1), result is zero:
1 2 3 4

0 ^ 0 == 0
0 ^ 1 == 1
1 ^ 0 == 1
1 ^ 1 == 0
 
COMPLIMENT: Effectively a bitwise "not". If the bit is 0, result is 1, otherwise result is 0:
The C++ operators perform these actions on each bit in the given values. For example:
1 2 3 4 5 6 7 8 9 10

int foo = 0x13 & 0x05;
cout << foo; // prints 1
// because...
/*
0x13 = %0001 0011
0x05 = %0000 0101
 & 
0x01 = %0000 0001
*/
 
Practical Uses: OR
OR is useful for making sure an individual bit is set. This is useful when combining "flags" as Cubbi illustrated:
1 2 3 4 5 6 7 8 9

// a flag would be a unique bit
const int flag1 = 0x01; // %0001
const int flag2 = 0x02; // %0010
const int flag3 = 0x04; // %0100
const int flag4 = 0x08; // %1000
// to combine flags:
int someflags = flag1  flag3;
// result is: 0x05 : %0101
 
The way this works is by "turning on" the desired bit, and leaving all other bits unchanged.
if we do: someflags = flag1;
someflags = %????
flag1 = %0001
 
%???1 < all bits stay unchanged except the low bit, which becomes 1

This is different from normal addition because addition will screw up the values if the flag is already set:
1 2 3

int someflags = flag1  flag3; // 0x05 : %0101
int good = someflags  flag3; // still 0x05 : %0101
int bad = someflags + flag3; // now 0x09 : %1001
 
As you can see, by using addition, we've actually cleared the desired flag and set an undesired one by mistake!
Practical Uses: AND, compliment
AND is often used to see if a specific flag has been set:
1 2 3 4

if( someflags & flag1 )
{
// here, we know flag1 is set in someflags
}
 
The way this works is by "turning off" all bits except the bits we're interested in (in this case, flag1's bit):
someflags = %????
flag1 = %0001
& 
%000? < all bits become zero except for the low bit

AND can also be used with the compliment operator to "turn off" a specific bit. Kind of like the reverse of the OR operation:
if we do: someflags &= ~flag1;
flag1 = %0001
~flag1 = %1110
someflags = %????
~flag1 = %1110
& 
%???0 < all bits unchanged except the low bit, which is forced to zero

Practical Uses: XOR
I'm too lazy to get into how this is commonly used. XOR effectively lets you toggle a bit:
someflags ^= flag1;
will set flag1 if it's clear, or clear it if it's already set.
Mostly this is used for encrypting stuff, since XOR doesn't "lose" any information. If you XOR a value with the same key twice, you get the original value.
That is:
1 2 3 4 5 6 7

int original = ...;
int key = ...;
int encypted = original ^ key;
int decrypted = encrypted ^ key;
if(original == decrypted) // < this will be true, regardless of what 'original' or 'key' are
 