#include <stream.h>
class A
{
public:
A() { cout << "A::A()" << endl; }
~A() { cout << "A::~A()" << endl; }
};
class B: public A
{
public:
B() { cout << "B::B()" << endl; }
~B() { cout << "B::~B()" << endl; }
};
int main()
{
A* a = new B;
delete a;
}
will result in:
A::A() B::B() A::~A()When class B needs to do something in its destructor (for example cleaning up some variables), this is definitely not what you want. Declaring
~A
as virtual will result in:
A::A() B::B() B::~B() A::~A()
class A
{
public:
A() { int i = 3; }
int geti() { return i; }
private:
int i;
};
When an instance of class A is initialized, calling geti will
most certainly not return 3, since it's not the member variable
i that is set in the constructor, but a local variable
i. Declaring a variable int i will hide the member variable
i. A solution to this is to append or prepend an underscore
'_' to each member variable and only to member variables; i_
will not clash with i.
#include <stream.h>
class A
{
public:
void func1() { cout << "A::func1, no problem" << endl; }
void func2(int newa) { a = newa; }
private:
int a;
};
int main()
{
A* aptr = 0;
aptr -> func1();
aptr -> func2(27);
return 0;
}
When the program is run, the output will be:
A::func1, no problem Memory fault - core dumped
The example shown here is bit more extreme than just not initializing; the object-pointer is a NULL-pointer. When the initialization of aptr to 0 is removed, the resulting behaviour is unpredictable; the program may or may not crash, depending on the value of the uninitialized pointer.
The solution to this problem is to always initialize object-pointers. If an object-pointer can not have a `decent' value (an allocated object) assigned to it, assign 0 to it; this will at least detect unauthorized access to the object-pointer.