Ricardo.B
Ricardo.B

Reputation: 33

(C++); Dynamically decide type of a function (derived class)

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

Answers (1)

Srini
Srini

Reputation: 1649

You don't need templates.

I've understood the following from your question

  1. You were given a submarine class, you renamed it ship
  2. You plan on making sub classes of ship, such as battleship, submarine etc
  3. You have some functions in the Game class which accept ship objects and you want to dynamically accept any derived class of ship.

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

Related Questions