views:

89

answers:

4

In C++ I have an array of pointers to Player objects and want to fill it with Fickle objects where Fickle is a class that is derived from Player. This is because I want a general Player array that I can fill with different objects from different classes that all are derived from the Player class.

How can I do this?

I create an array of pointers to Player objects

Player ** playerArray;

Then initialize the array to a certain size

playerArray = new Player *[numPlayersIn];

But then the following does not work for some reason:

playerArray[i] = new Fickle(0);

How can I fill the playerArray with Fickle objects (Fickel is a class derived from Player) ?

Thanks.

UPDATE:

I get the error message (in Eclipse IDE):

expected ';' before 'Fickle'

I think it might be something to do with the definition of Fickle.

The Fickle.hpp file contains:

#pragma once
#include "player.hpp";

class Fickle: public Player {
public:
    // constructor
    Fickle(int initChoice){
        choice = initChoice;
    }
}

Is this OK or is there a problem with this?

The Player class header file has:

class Player {
private:

public:
    int getChoice();
int choice; // whether 0 or 1
virtual void receive(int otherChoice); // virtual means it can be overridden in subclases
};

The receive method will be overridden in Fickle and other classes derived from the Player class

UPDATE 2:

OK I think the error is actually due to a different part of the code.

Player defines a method receive:

virtual void receive(int otherChoice);

That should be overridden by the subclass Fickle but the definition in Fickle:

void Fickle::receive(int otherChoice) {}

gives the error:

no 'void Fickle::receive(int)' member function declared in class 'Fickle'

But I don't know why this is because receive is defined in the Player class?

+3  A: 

While you probably should be using a vector instead, there's no real reason a dynamically allocated array can't work. Here's a bit of working demo code:

#include <iostream>

class Player {
public:
    virtual void show() { std::cout << "Player\n"; }
};

class Fickle : public Player {
public:
    virtual void show() { std::cout << "Fickle\n"; }
};

int main() {
    Player **p = new Player *[2];
    p[0] = new Player;
    p[1] = new Fickle;

    for (int i=0; i<2; i++)
        p[i]->show();

    for (int i=0; i<2; i++)
        delete p[i];
    delete [] p;
    return 0;
}
Jerry Coffin
Why is Player declared as a struct here? Does it make a difference if Player is a class instead of a struct?
tree-hacker
@tree-hacker: it just saves putting in a `public:`. That's the only real difference it makes. To save confusion, I've made both classes with `public:`.
Jerry Coffin
A: 

Does Fickle have a constructor that accepts an int or pointer type? Is it privately derived from Player? Otherwise it looks like this should work.

Mark B
Yes Fickle does have an int constructor. It is publicly derived from Player I think (see code in question) but am not too sure about derived classes.
tree-hacker
+2  A: 

It looks like you forgot a semicolon at the end of Fickle class:

class Fickle: public Player {
    // ...
}; // <---- this semicolon

Maybe somewhere else.

UPDATE 2: When you override a virtual function in the derived class you must declare it there too.

ybungalobill
For such a common mistake it's surprisingly hard to track down.
Mark Ransom
@Mark Ransom: Blame C++ preprocessor. It's especially hard when it comes from the end of some include. When I was a newbie I wasted a hour to track this error once.
ybungalobill
OK I didn't know you had to declare overridden functions in the derived class as well.
tree-hacker
+1  A: 

If it's not compiling correctly, then you probably didn't #include the header that defines Fickle in the same source file you have that code. Usually an error like that means the compiler doesn't know what Fickle is.

MSN
Yes turned out that was what one of the problems was thanks.
tree-hacker