HumanBeing
is a constructor. Whenever possible, you should use the base/member initializer syntax of a constructor to initialize the members and base class portions:
HumanBeing(string name, int age)
: name(name) // error!
, age(age) // error!
{
// what to do in here? Nothing!
}
However, that won't work here (see error!
comments) because the members age
and name
are pointers.
This is a problem, because the constructor arguments are temporary objects. We must not store, inside the class object, pointers to temporary objects. And so we cannot fix it like this, even though it compiles:
HumanBeing(string name, int age)
: name(&name)
, age(&age)
{
}
The parameter objects name
and age
cease to exist when the constructor terminates, and so the object's members are left pointing to garbage.
You must redesign the constructor with a different interface, or redesign the class so that its members aren't pointers.
// Alternative constructor: get stable objects from somewhere
HumanBeing(string *n, int *a)
: name(n)
, age(a)
{
}
// Alternative class design
class HumanBeing {
private:
string name;
int age;
HumanBeing(string n, int a)
: name(n)
, age(a)
{
}
};
There is rarely any need to fuss around with the this
pointer. The main use is when a non-static member function needs to call another function in another class, or a non-class function, and needs to pass a pointer to its object. For instance:
// FooClass derives from NotificationTarget
// The this pointer is FooClass *, and
// implicitly converts to NotificationTarget * in the RegisterMe call.
FooClass::RegisterForNotification(NotificationSource &ns)
{
ns.RegisterMe(this); // void NotificationSource::RegisterMe(NotificationTarget *);
}
The this
pointer can be used to overcome a scoping problem in C++:
int xl; // at file scope
class funny {
int x1;
void method()
{
xl = 1; // TYPO! assigns to xl at file scope, not x1 member.
this->xl = 1; // TYPO! But caught by compiler.
}
};
This doesn't add up to a reason to use this->member
all over the place in C++ programs; you must use sane naming conventions to defend against this type of problem, such as using g_
prefix on globals, and m_
on members, or a similar convention.