Hlynkacg said:
I've already created a basic "Instrument" class from which all of the different displays are derived, but I'm not sure how to proceed.
The problem is that unlike the switches which are all essentially identical. The displays come in many forms, and as a result the constructors for each are unique, so it isnt as simple as creating a single "CreateDisplayFunction" and adding that instance to a map.
Ok. This whole setup relies on the fact that you can have a collection of base class pointers that call derived class methods when invoked.
Some theory:
Normally, if you try to set a base class variable equal to a derived class, the extra derived class methods get "sliced" and removed.
Code:
class Animal
{
public:
Animal() {}
virtual void Speak() {printf("I'm an animal!");}
}
class Dog::public Animal
{
public:
Dog() : Animal() {}
void Speak() {printf("Bark");}
}
//somewhere later
Animal myAnimal = Dog();
//if myAnimal.Speak() is called, it will print "i'm an animal", as the extra
//dog methods/implementations have been sliced off
We avoid that if we use pointers
Code:
Animal * myAnimal = new Dog();
//now, myAnimal->Speak() will print "Bark", as the computer figures
//out that that pointer actually points to a Dog
Now, enough of the animal classes.
First, you have to define the base class, with any and all of the public methods that derived Instruments should call. (This base class is similar to an interface in other languages, like C#)
Code:
class Instrument
{
public:
Insturment();
virtual bool RegisterArea () [COLOR="Red"]= 0[/COLOR];
virtual bool RedrawEvent () [COLOR="Red"]= 0[/COLOR];
}
Note the function signatures. The virtual, like normal, allows the function to be overridden in derived classes. The "= 0" makes a function a "pure virtual" function; basically, it has no definition in that class. This forces any derived classes that are actually constructed to have a definition for that function. Effectively, the "= 0" is just error prevention, as the computer will throw an error if you try to create a derived class that does not implement one of the pure virtual functions.
Now, to hold all your instruments, just create a vector that holds pointers to Instrument. This will probably be in the vessel definition.
Code:
std::vector<Instrument *> VesselInstruments;
Now, you need to create a function that creates each of the instruments. Unlike some of my stuff, you will determine the instruments pre-compile-time, so just create a function inside whatever class holds the instruments- again, this is probably in the vessel class.
Inside the createInstruments function, just push back pointers to the derived types into the vector.
Code:
//assuming there are derived classes
//LCDInstrument, FooInstrument, BarInstrument
bool createInstruments()
{
//create the LCD's
VesselInstruments.push_back(new LCDInstrument(10, "Fuel Quantity")) //obviously replace with whatever the constructor actually is
VesselInstruments.push_back(new LCDInstrument(15, "Fuel Flow"));
//to demonstrate additional setup before adding the instrument to the main vector
FooInstrument * foo1 = new FooInstrument();
foo1->setUpGrid();
VesselInstruments.push_back(foo1);
//create bar instrument
VesselInstruments.push_back(new BarInstrument());
}
Now, just like in the VC switches, you just call the base class methods. Note that it is impossible to call any derived class public method that does not exist in the base class.
Code:
void registerInstrumentAreas()
{
for (int i = 0; i < VesselInstruments.size(); i++)
{
VesselInstruments[i]->RegisterArea();
}
}
void redrawInstruments()
{
for (int i = 0; i < VesselInstruments.size(); i++)
{
VesselInstruments[i]->RedrawEvent();
}
}