juanchopanza gave you the right answer about what you asked: you can assign a pointer of the child type into a pointer of the parent type, because the child class is also of the type of the parent class.
A derived object is a base class object (as its a sub class), so can be pointed to by a base class pointer. however a base class object is not a derived class object so can't be assigned to a derived class pointer.
I will use an analogy: a dog is an animal, a cat is an animal. You cannot say that an animal is always a cat or dog.
In C++, run-time type checking is implemented through dynamic_cast, this allows you to check if the parent class if of a certain type of children class (in my analogy this allows you to check if an Animal is a Cat). Compile-time downcasting is implemented by static_cast, but this operation performs no type check. If it is used improperly, it could produce undefined behavior.
In general abuse of downcasting shows bad design of interfaces unless you are implementing things like a double dispatch pattern, you should not have to resort to downcasts all the time in your program.
On another note, please capitalize your classes, this is fairly standard across most if not all C++ conventions. I fixed all the other stuff in your program and it should compile.
#include <iostream>
using namespace std;
class PolyTest
{
public:
virtual ~PolyTest() {} // your example had no body
virtual void type();
};
void PolyTest::type()
{
cout << "first gen";
}
class PolyChild: public PolyTest
{
public:
void PolyChild::type();
};
void PolyChild::type()
{
cout << "second gen";
}
int main()
{
PolyTest* ptr1 = new PolyTest();
PolyTest* ptr2 = new PolyChild();
ptr1->type();
ptr2->type();
cout << std::endl;
PolyChild* pChild1 = dynamic_cast<PolyChild*>(ptr1);
if (pChild1)
cout << "ptr1 is a PolyChild" << std::endl;
else
cout << "ptr1 is NOT a PolyChild" << std::endl;
PolyChild* pChild2 = dynamic_cast<PolyChild*>(ptr2);
if (pChild2)
cout << "ptr2 is a PolyChild" << std::endl;
else
cout << "ptr2 is NOT a PolyChild" << std::endl;
cin.ignore(1);
return 0;
}
I also added a bit of code to demonstrate dynamic_cast<>. Again, you should not abuse it as abusing it, means that you did not design your interfaces properly.