I would like to declare the type of an object based on user input.

Ie. I would like to do the following:

string obj = //get from command line arguments
	if(Format == "obj")
		ObjFile Obj;

	else if (Format == "vtk")
		VtkFile Vtk;

//the list goes on...

But to possibly 10-ish file types, without having a 5 page long list of if's. Is this possible? Something like

//somehow make an object of the correct type called GoodObject



If each class derives from the same base class inheriting virtual functions then it may be possible to do something with pointers that looks vaguely like:

class base
   virtual A()
   virtual B()
   virtual C()
class V : public base
class C: public base
int main()
base * ptr;
string CLArg[];
int numComm;
for(i = 0; i < numComm; ++i)
  if(CLArg[i] == "V")
    classType = 1;
  else if(CLArg[i] == "C")
    classType = 2;

    case 1: ptr = new V;
    case 2: ptr = new C;


Try this (add includes):

using std::flush;
using std::cout;
using std::endl;
using std::cin;

class Aircraft {
    Aircraft() { cout << "Aircraft is up!" << endl; }
    virtual ~Aircraft() {}
    virtual void doSomething() = 0;

class Fighter: public Aircraft {
    ~Fighter() { cout << "Fighter landed." << endl; }
    void doSomething() { cout << "Z-z-z-z..." << endl; }

class Bomber: public Aircraft {
    ~Bomber() { cout << "Bomber crashed." << endl; }
    void doSomething() { cout << "Zh-zh-BANG" << endl; }

int main()
    Aircraft* plane;
    char reply;

    while (cout << "Enter f|b|q: " << flush, cin >> reply) {
        switch (reply) {
        case 'f':   plane = new Fighter;break;
        case 'b':   plane = new Bomber; break;
        default: plane = 0; break;
        if (plane == 0)
        delete plane;
    return 0;

I still have the same question - why can you use

new Fighter

to assign an Aircraft variable?

Because any Fighter object IS an Aircraft too, look at

class Fighter: public /* inherites from */ Aircraft

So my plane pointer refers to an Aircraft of type Fighter, then it refers to another Aircraft - bomber of type Bomber.
Both a fighter and a bomber are aircrafts.

But not vice versa. It's wrong code:

Aircraft* plane = new Fighter;
Fighter* f15c = plane;

You can't directly assign a pointer to base class to a pointer to derived class. May be the 1st one refers to bomber object now...
In actual fact sometimes you can do that via dynamic_cast construct, but it's another story...

I'm convinced that works, but I'm still not sure why.

It is my understanding that when you make a pointer Aircraft* that a pointer is created which points to an address of the size required to hold all of the members of Aircraft. However, there are additional members (more than Aircraft) in Fighter because Fighter inherits all of Aircrafts members and then defines additional ones. So it seems that the Aircraft pointer would be "too small" to fit everything in Figher. Am I way off here?

A pointer does not fit anything except an address. It can't be "too small". It is a pointer - that's all.

If you dereference (with unary operator *) a pointer to Aircraft, you get only common part of all Aircrafts. For example, if the plane pointer refers to the Fighter object, *plane expression gets only Aircraft object part of that fighter...

But if you call virtual (only virtual) member functions via base class pointer (or via reference to base class) then true derived class object functions are called. Why? It's funny but the most silly answer is correct: that's C++ rules!

It's C++ implementation of the OOP polymorphism notion.

I see - thats what I meant by "too small", that when you dereference a derived class which is of type Aircraft* then you wouldn't get everything, but I guess that is correct!

Thanks for your help!

I see - thats what I meant by "too small", that when you dereference a derived class which is of type Aircraft* then you wouldn't get everything, but I guess that is correct!

Please, be more thorough: when you dereference a pointer to base class referred to an object of derived class...
It's so called slicing.

This article has been dead for over six months. Start a new discussion instead.