Moved and merged topics. They are essentially the same question.
What you seem to be asking about, is how to use virtual functions, and run-time/dynamic dispatch. Here is how you make it work.
First, you create a base class with the commonalities in it, such as functions with the same name and parameter list and return type.
class ConstructionVehicle // : Vehicle // (Probably derived from a Vehicle class)
{
public:
virtual void build() = 0; // Pure virtual function (=0), has no implementation
};
The "= 0" part is important, otherwise the compiler will complain if you don't supply a function definition, which it won't really make sense to have in a base class. After all, how would the function know to build anything if it didn't yet know what it was building. Also keep in mind that a class with any pure virtual functions can never be instantiated. It can only be derived from. The derived classes must implement those missing functions before a class of that type can be created.
Next you create your derived classes that inherit from the base class.
class ConVec : public ConstructionVehicle // Dervied from above base class
{
public:
void build(); // Virtual is optional, definately don't use =0 (pure virtual)
};
class RoboMiner : public ConstructionVehicle // Derived from above base class
{
public:
void build(); // Virtual is optional, definately don't use =0 (pure virtual)
};
Now make sure to implement those functions in the derived class, each with their own respective code.
void ConVec::build()
{
// ConVec construction code goes here....
}
void RoboMiner::build()
{
// RoboMiner construction code goes here....
}
Now you create instances of the derived class, and store them using a pointer to the base class.
int main()
{
// Means "ConstructionVehicle*[2] builderArray;" in Java/D notation (which is usually easier to read)
ConstructionVehicle *builderArray[2];
// Populate the array with construction vehicle instances (using derived classes)
// This uses dynamic memory allocation (flexible, but a little slower)
builderArray[0] = new ConVec();
builderArray[1] = new RoboMiner();
// Similarly, you could have used static memory allocation (less flexible, but fast)
//ConVec conVec();
//RoboMiner roboMiner();
//builderArray[0] = &conVec;
//builderArray[1] = &roboMiner;
int i;
// Call derived build function of each class
for (i = 0; i < 2; ++i)
{
builderArray[i]->build(); // Use -> instead of . notation, since we're using pointers
}
}
Then the proper build function will be called for each derived class. This is easily verified with two different cout/printf statements for those function bodies.
Note that it is very important that instances created of the derived classes are stored into pointers of the base class type for the dynamic dispatch to work and be useful.
I should point out that this will not work without the virtual declaration in the base class. You could remove the pure virtual part and it'd still work, provided you stubbed out a default build function to be inherited by the other classes. The virtual keywork is what tells the compiler to use a virtual function table to figure out what function to call at runtime, rather than hardcode a function address at the point of call. Without the virtual keywork, you would be calling the build function on the base class instead of the derived classes. Keep in mind that virtual functions take slightly longer to call due to the table lookup. This is almost never an issue, but if you have a tiny function with little to no code in it, and it's called many times in a tight loop, you may notice a performance hit.
Also note that I dropped the virtual keywork in the derived classes. This is because I don't expect any classes to derive from those last two classes. They are essentially "leaf" classes in the class hierarchy tree. (In Java, virtual seems to be the default, and "final" methods I believe are the non-virtual ones, so they've reversed where you need to use a keyword). The point of not declaring the leaf class functions as virtual, is to allow for some speed optimization. If the compiler knows for sure what the data type is, it can make a direct call using a hardcoded function address. This happens if you call functions through a variable of the derived class type rather than the base class type, or if you call other member functions from within the class. If you declare the function as virtual in the derived class, than the compiler assumes there may be more derived classes, and so the virtual function table must be used in those cases as well.
void f()
{
// Create pointers to base and derived classes
ConstructionVehicle* cv1;
ConVec* cv2;
// Fill in those pointers with objects of the same type
cv1 = new ConVec();
cv2 = new ConVec();
// Call a function declared as virtual in the base class
cv1->build(); // Virtual function class, slightly slower (cv1 is of type ConstructionVehicle*, which declares build as virtual)
cv2->build(); // Direct call, faster (cv2 is of type ConVec*, which does not declare build as virtual)
}
Note you may want to look into
interfaced based programming. Interfaced based programming suggests only
pure virtual functions be shared, and not regular functions or class member variables. An often good source of information for interfaced based programming are documents describing COM (the Component Object Model), although, be aware that interfaces are just one of the fundamentals of COM, and that COM added a lot of other things, which a number of people think aren't so hot. These days COM is considered somewhat of a legacy technology, but interfaced based programming is probably more important than ever.