Sunday, June 22, 2008

Creating An Immutable Object

An immutable object is an object that once gets created can no longer changed its state afterwards.
For example, to make a class immutable we can do the following:

class A
{
//1. we make its attributes private.
int x,y;
public:
//2. only create getters if needed, no setters of course
int getx() const {return x;} //same for y
public:
//3. declare an explicit constructor
explicit A(int _x, int _y) : x(_x), y(_y){}
};

We make the attributes private so derived classes cannot change the state. Of course, getters should return copies not references to the attribute.

Friday, June 20, 2008

Const Pointers, Pointers to Const, Volatile

Constant Pointers and Pointers to Const

Honestly, the first time I saw these statements, I got a bit confused.
const int * p;
int * const q;
const int * const r;

It is easy actually. The technique is to read from right to left. But note that const type  and type const are the same. So const int and int const are equivalent as well as const Object and Object const.

p is a pointer to a constant integer. This means that the following is valid:
const int xx = 10;
int xy = 11;
p = &xx; //okay
p = &xy; //okay
But p cannot be used to modify the value at the address it dereferences because it is constant.
*p = 120; //error

q is a constant pointer to an integer. This means that once initialized, q can never be set again.
q = &xx; //okay
q = &xy; //error

r is a constant pointer to a constant integer. This is a combination of the two rules above.

Volatile

The volatile keyword is used to denote that the compiler cannot make assumptions on its value and not optimize.

Memory Management

Creation of an object can either be on the heap or the stack.
Stack objects are usually created by 
Object i;
whereas heap objects are created by
Object* p = new Object;

The only difference is that the destructor of the object created on the stack is invoked when the object gets out of scope, whereas to invoke the destructor for an object created on the heap we need to explicitly delete the object. 

Restricting Object Creation
I will discuss how we can force creation of an object on a specific location -- that is heap or stack.

Heap Only
To restrict the creation of an object on the heap, that is the object will only be created via new, the destructor should be declared as private.

class Object
{
private:
~Object();
};

The following code will fail to compile.
int main(int argc, char* argv[])
{
Object obj;
};

When the object gets out of scope, the destructor cannot be accessed because it is private.
This will force us to create the object on the heap.

int main(int argc, char* argv[])
{
Object* obj = new Object;
};
Now, the question is how do we delete the object since we cannot access the destructor?
We add a public function in class Object, say destroy().
 
void Object::destroy()
{
delete this;
}
So now we can do,
int main(int argc, char* argv[])
{
Object* obj = new Object;
// do other stuffs here
obj->destroy();
// obj is no longer valid here
};

Stack Only
To restrict the creation of an object on the stack, the trick is to not allow the use of operators new, as well as operator delete for completeness. To do this, we hide new and delete. So the class should look like
class Object
{
private:
void* operator new();
void operator delete();
};
For some advance compiler, the definition of the operators are not required. But for some compilers that do require, we can create an empty definition for the operators. Also, for completeness we should also override and hide the array versions of operators new and delete.

Monday, May 19, 2008

Why Blog?

This is the first time I tried blogging! My reason is personal -- simply to have a kind of central store for ideas that suddenly comes to mind. I believe that writing what I learn helps in retention -- lots of things just go *poof* when you do not have a concrete take on them. One other reason is that other people's comments can be helpful sometimes. I will be delighted if this helps other people in any way.
This blog mainly tackles on my experience (or the lack of it) with the Boost C++ library. Along the way I may mention other facets of C++, like generic programming, templates and other related stuffs.
So long for now!