Reputation: 33
I am new to C++ and I am stuck in my program. It is a program that mimics the board game "Battleship". We were given code to edit, and one of the things we were asked to do was to make the program prompt you for which kind of ship you wanted to lay down (just 1 ship at the moment).
We were given a certain ship class (Submarine) to start, which I made into a Ship parent class. I was planning on using derived classes for each of the ship types, but the functions under the Game class have a parameter of the original Submarine class (&submarine) (which is now Ship, so the parameter is &Ship). I am trying to figure out how to dynamically decide the type of the parameter so I can use the function for which ever ship is placed.
Is there a way to do this? We just learned parent/child classes and have not learned templates yet, which is a common method I have been seeing. I have also seen a lot of use of virtual functions for solutions similar to mine but I don't quite understand how that would help my situtation.
Here is an example of a function that I talked about before (under the Game class):
bool placePiece(Ship& piece) // Ship is parent class -- want it to be derived class (1 of 5 options) depending on which class is being used
{
cout << "What coordinate do you want to place the " << toLower(piece.getName()) << " (length "<<piece.getLength()<<") at?\n";
string coordinate = toLower(requeststring());
cout << "What direction do you want the piece to go? (up, down, left or right)\n";
string direction = toLower(requeststring());
piece.setPiece(rowCharToInt(getFirstChar(coordinate)), getFirstInt(coordinate)-1, getFirstChar(direction));
return isValidPlacement(playerBoard, piece);
}
Please let me know if any more information is needed!
Thank you
Upvotes: 0
Views: 137
Reputation: 1649
You don't need templates.
I've understood the following from your question
Correct?
You only need templates when you want the types you are accounting for have no relation at all. which is not the case here.
By virtue of polymorphism your methods will already be able to handle that which you want.
Consider a simple example as below
#include <iostream>
class Base {
public:
int a;
};
class Derived : public Base {
public:
int b;
};
void doge(Base foo) {
std::cout << "My a value: " << foo.a << std::endl;
}
int main() {
Derived d;
d.a = 5;
doge(d);
return 0;
}
Notice how the doge
function accepts and expects a Base object, but we send it a Derived object. This works because this is inherently guaranteed by class polymorphism.
As long as depending on the type of ship you don't do something different, your methods should work. However if this is the case it would be better to make use of overloaded functions and casting
This also leads into an OOP principle called the Liskov Substitution Principle. The principle requires you to model your base and derived class objects in such a way that objects of a derived class can always stand in for a base class.
Upvotes: 1