1)
The problem is that when the version of foo() that takes an argument calls the version that doesn't, the "this" pointer in that function is invalid.
It's not invalid. Try this code:
Code:
include <iostream>
using namespace std;
class foo
{
public:
foo()
{
cout<<this<<endl
<<"Object being created with default constructor."<<endl;
}
foo(bool bar)
{
cout<<"Object being created with parameterized constructor."<<endl
<<this<<endl;
if(bar)
foo();
}
};
int main()
{
foo f(true);
return 0;
}
or
Code:
#include <iostream>
using namespace std;
class foo
{
public:
foo()
{
cout<<"foo() construtor:"<<endl;
DoStuff(); //'this' is used to call DoStuff()
}
foo(bool bar)
{
cout<<"foo(bool bar) constructor:"<<endl;
DoStuff(); //'this' is used to call DoStuf()
if(bar)
foo();
}
void DoStuff()
{
cout<<"Doing something here."<<endl;
}
};
int main()
{
foo f(true);
return 0;
}
2)
Code:
class foo
{
public:
foo() {}
DoStuff()
{
//Stuff getting done...
}
};
class foobar : public foo
{
public:
foobar() {}
DoStuff()
{
//Different stuff getting done...
}
};
DoFoobarStuff(foo& foobar)
{
//When you pass this function a class of the foobar type typecast as a foo type, the foobar version
//of DoStuff() should get called
foobar.DoStuff();
//However, no matter which type is passed, only the foo version of DoStuff() is ever used
}
Case 1: You pass the function a foo object, and the foo version of DoStuff() is called.
Case 2: you pass the function a foobar object that is typecast to a foo object. That typecast causes "object slicing": the foobar part of the object is sliced off and discarded.
When you use a pointer to base type variable, object slicing doesn't occur when you assign the address of a derived object to the pointer. If you dereference the pointer, the foobar object is sliced off once again.
The virtual keyword in front of a function name tells the compiler you want what's called "dynamic binding". Dynamic binding means you want the version of the function corresponding to the type of the object stored in a variable rather than the version of the function corresponding to the type of the variable. Here is an example:
foo* p = &myFoobarObject;
p->DoStuff();
If DoStuff() is virtual, then dynamic binding causes the DoStuff() version in the class of the object assigned to p, i.e. foobar, to execute. If DoStuff() is not virtual, then "static binding" occurs and the version of DoStuff() in the pointer type, i.e. foo, is called. So, a variable that is of pointer to base class type has both a "static type" and a "dynamic type". The static type is the type of the pointer; the dynamic type is the type of the object assigned to the pointer.
By the way, all member functions that aren't constructors should specify a return type:
void DoFoobarStuff(foo& foobar)