I am trying to create a vector of objects that can have pointers to functions. I would appreciate some help with this as I don't really know what to do

#include <stdlib.h>
#include <windows.h>
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Card
{ public:

      typedef void (*FunctType)(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &, vector< vector<Card> > &, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard, int &, int &);
      FunctType GetEffect() {return *Effect;}
      void SetEffect(FunctType* setEffect) {Effect = setEffect; }
      string GetName() {return Name;}
      void SetName(const string& setName) {Name = setName; }

private:
      FunctType* Effect;
      string Name;

};

typedef void (*FunctType)(
               vector<Card> &,
               vector<Card> &,
               vector< vector<Card> > &,
               vector<Card> &,
               vector<Card> &);

vector<Card> KaibaDeck(40);
vector< vector<Card> > Field(4, vector<Card>(5));
vector<Card> KaibaHand;

//void KMP( FunctType* fn )
void KMP(vector<Card> &KaibaDeck)
{
    vector<Card> v1;
    vector<vector<Card> > v2;
    int num;
    cout<<"enter a number"<<endl;
    cin>>num;
KaibaHand.push_back(KaibaDeck[num]);
     Field[0][0]=KaibaHand[0];
Field[0][0].GetEffect();// problem here
}

void HEAVYSTORM(vector<Card> &,
                vector<Card> &,
                vector< vector<Card> > &,
                vector<Card> &,
                vector<Card> &)
{
    cout<<"This card destroys ALL magic and traps cards on the field!!"<<endl;
        for (int i=0; i<5; i++)
        {
            Field[3][i]=Card();
        }   
}

void POTOFGREED(vector<Card> &,
                              vector<Card> &,
                              vector< vector<Card> > &,
                              vector<Card> &,
                              vector<Card> &)
{cout<<" pot of greed"<<endl;}

int main()
{
   // FunctType vector<Card> KaibaDeck(2);
        vector<Card> KaibaDeck(2); //I have no idea what to do here. I just want a Card() vector that can store functions OR have the SetEffect member function be able to take in the HEAVYSTORM and POTOFGREED functions
    //KaibaDeck[0] = HEAVYSTORM;
    //KaibaDeck[1] = POTOFGREED;

    KaibaDeck[0].SetEffect(HEAVYSTORM);
    KaibaDeck[1].SetEffect(POTOFGREED);
    KMP(KaibaDeck);
        return 0;
}

Recommended Answers

All 12 Replies

Your HEAVYSTORM and POTOFGREED function implementations (at lines 50 and 63, respectively) need to provide argument names for each argument, whether or not you use the args in the function.

As far as I can tell at a quick glance, your use of function-pointers is ok as-is. What compile-time or run-time errors are you seeing?

I tried this below and got the error: "error C2664: 'Card::SetEffect' : cannot convert parameter 1 from 'void (__cdecl *)(std::vector<_Ty> &,std::vector<_Ty> &,std::vector<_Ty> &,std::vector<std::vector<_Ty>> &,std::vector<_Ty> &,std::vector<_Ty> &)' to 'Card::FunctType *'"

#include <stdlib.h>
#include <windows.h>
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Card
{ public:

      typedef void (*FunctType)(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard);//, int &KaLP, int &YuLP);
      FunctType GetEffect() {return *Effect;}
      void SetEffect(FunctType* setEffect) {Effect = setEffect; }
      string GetName() {return Name;}
      void SetName(const string& setName) {Name = setName; }

private:
      FunctType* Effect;
      string Name;

};

typedef void (*FunctType)(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard);

vector<Card> KaibaDeck(40);
vector< vector<Card> > Field(4, vector<Card>(5));
vector<Card> KaibaHand;
vector<Card> KaibaGraveyard;
vector<Card> YugiGraveyard;
vector<Card> YugiDeck;


//void KMP( FunctType* fn )
void KMP(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard)
{
    vector<Card> v1;
    vector<vector<Card> > v2;
    int num;
    cout<<"enter a number"<<endl;
    cin>>num;
KaibaHand.push_back(KaibaDeck[num]);
     Field[0][0]=KaibaHand[0];
Field[0][0].GetEffect();// problem here
}

void HEAVYSTORM(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard)
{
    cout<<"This card destroys ALL magic and traps cards on the field!!"<<endl;
        for (int i=0; i<5; i++)
        {
            Field[3][i]=Card();
        }   
}

void POTOFGREED(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard)
{cout<<" pot of greed"<<endl;}

int main()
{
   // FunctType vector<Card> KaibaDeck(2);
        vector<Card> KaibaDeck(2); //I have no idea what to do here. I just want a Card() vector that can store functions OR have the SetEffect member function be able to take in the HEAVYSTORM and POTOFGREED functions
    //KaibaDeck[0] = HEAVYSTORM;
    //KaibaDeck[1] = POTOFGREED;

    KaibaDeck[0].SetEffect(HEAVYSTORM);
    KaibaDeck[1].SetEffect(POTOFGREED);
    KMP(KaibaHand, KaibaDeck, YugiDeck, Field, KaibaGraveyard, YugiGraveyard);
        return 0;
}

It's probably most readable (and sane) if GetEffect returns a FunctType* rather than trying to dereference the pointer before returning. Also, since HEAVYSTORM and POTOFGREED are both of type FunctType and SetEffect() expects a FunctType* (the error message you're seeing), try passing an explicit pointer, e.g. KaibaDeck[0].SetEffect(&HEAVYSTORM); (note the '&').

When you retrieve the function-pointer, you also presumably need to invoke it with arguments. At line 46, try above, try something like:

FunctType *effect = Field[0][0].GetEffect();
effect(KaibaHand, KaibaDeck, YugiDeck, Field, KaibaGraveyard, YugiGraveyard);

If you get an type-error on the line where you call effect(), try dereferencing the pointer right there (but I'm not sure you need to, pointers to functions are slightly odd in C/C++). e.g. (*effect)(same args...);

I tried the code below and now got the errors:
(15):error C2440: 'return' : cannot convert from 'Card::FunctType *' to 'Card::FunctType'
(46):error C2440: 'initializing' : cannot convert from 'Card::FunctType' to 'FunctType *'
(47): error C2064: term does not evaluate to a function taking 6 arguments
(69): error C2664: 'Card::SetEffect' : cannot convert parameter 1 from 'void (__cdecl *)(std::vector<_Ty> &,std::vector<_Ty> &,std::vector<_Ty> &,std::vector<std::vector<_Ty>> &,std::vector<_Ty> &,std::vector<_Ty> &)' to 'Card::FunctType *'

#include <stdlib.h>
#include <windows.h>
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Card
{ public:

      typedef void (*FunctType)(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard);//, int &KaLP, int &YuLP);
      FunctType GetEffect() {return Effect;}
      void SetEffect(FunctType* setEffect) {Effect = setEffect; }
      string GetName() {return Name;}
      void SetName(const string& setName) {Name = setName; }

private:
      FunctType* Effect;
      string Name;

};

typedef void (*FunctType)(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard);

vector<Card> KaibaDeck(40);
vector< vector<Card> > Field(4, vector<Card>(5));
vector<Card> KaibaHand;
vector<Card> KaibaGraveyard;
vector<Card> YugiGraveyard;
vector<Card> YugiDeck;


//void KMP( FunctType* fn )
void KMP(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard)
{
    vector<Card> v1;
    vector<vector<Card> > v2;
    int num;
    cout<<"enter a number"<<endl;
    cin>>num;
KaibaHand.push_back(KaibaDeck[num]);
     Field[0][0]=KaibaHand[0];
FunctType *effect = Field[0][0].GetEffect();// problem here
*effect(KaibaHand, KaibaDeck, YugiDeck, Field, KaibaGraveyard, YugiGraveyard);
}

void HEAVYSTORM(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard)
{
    cout<<"This card destroys ALL magic and traps cards on the field!!"<<endl;
        for (int i=0; i<5; i++)
        {
            Field[3][i]=Card();
        }   
}

void POTOFGREED(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard)
{cout<<" pot of greed"<<endl;}

int main()
{
   // FunctType vector<Card> KaibaDeck(2);
        vector<Card> KaibaDeck(2); //I have no idea what to do here. I just want a Card() vector that can store functions OR have the SetEffect member function be able to take in the HEAVYSTORM and POTOFGREED functions
    //KaibaDeck[0] = HEAVYSTORM;
    //KaibaDeck[1] = POTOFGREED;

    KaibaDeck[0].SetEffect(&HEAVYSTORM);
    KaibaDeck[1].SetEffect(&POTOFGREED);
    KMP(KaibaHand, KaibaDeck, YugiDeck, Field, KaibaGraveyard, YugiGraveyard);
        return 0;
}

Line 15 needs to return a FunctType*:

FunctType* GetEffect() {return Effect;}

And my bad, I should have noticed this before, C++ has no good way of knowing that the FunctType typedef defined inside class Card is the same as the one declared outside. Since Card::FunctType is public anyway, just use that (and specify it that way outside of Card methods), and delete the external one. Specifically, at line 46:

Card::FunctType *effect = Field[0][0].GetEffect();// problem here

Does this get you close?

Also, I suspect that your desire to use function pointers this way stems from a lack of understanding about deriving subclasses (though it will eventually still work). Instead of having only a single Card class, with an externally-defined Effect function-pointer attached to it, start with a BaseCard class (with an Effect() method which may do nothing, if that's appropriate) and then derive specific card-types such as HeavyStormCard, which reimplement the Effect() method to do the right thing for that card. You can then have a vector of type BaseCard* which can contain instances of that or any class derived from it: vector<BaseCard*> KaibaHand; Note that you have to allocate and delete cards, because vector<> needs a constant-sized object (in this case a pointer is always pointer-sized) to do its job. But that's a small price to pay for polymorphism (the ability to store objects of different classes all in the same container). Cheers!

I'm getting really confused. Now the errors I'm getting are:
(47): error C2064: term does not evaluate to a function taking 6 arguments

(69): error C2664: 'Card::SetEffect' : cannot convert parameter 1 from 'void (__cdecl *)(std::vector<_Ty> &,std::vector<_Ty> &,std::vector<_Ty> &,std::vector<std::vector<_Ty>> &,std::vector<_Ty> &,std::vector<_Ty> &)' to 'Card::FunctType *'

(70): error C2664: 'Card::SetEffect' : cannot convert parameter 1 from 'void (__cdecl *)(std::vector<_Ty> &,std::vector<_Ty> &,std::vector<_Ty> &,std::vector<std::vector<_Ty>> &,std::vector<_Ty> &,std::vector<_Ty> &)' to 'Card::FunctType *'

#include <stdlib.h>
#include <windows.h>
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Card
{ public:

      typedef void (*FunctType)(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard);//, int &KaLP, int &YuLP);
      FunctType* GetEffect() {return Effect;}
      void SetEffect(FunctType* setEffect) {Effect = setEffect; }
      string GetName() {return Name;}
      void SetName(const string& setName) {Name = setName; }

private:
      FunctType* Effect;
      string Name;

};

//typedef void (*FunctType)(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard);

vector<Card> KaibaDeck(40);
vector< vector<Card> > Field(4, vector<Card>(5));
vector<Card> KaibaHand;
vector<Card> KaibaGraveyard;
vector<Card> YugiGraveyard;
vector<Card> YugiDeck;


//void KMP( FunctType* fn )
void KMP(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard)
{
    vector<Card> v1;
    vector<vector<Card> > v2;
    int num;
    cout<<"enter a number"<<endl;
    cin>>num;
KaibaHand.push_back(KaibaDeck[num]);
     Field[0][0]=KaibaHand[0];
Card::FunctType *effect = Field[0][0].GetEffect();// problem here
*effect(KaibaHand, KaibaDeck, YugiDeck, Field, KaibaGraveyard, YugiGraveyard);
}

void HEAVYSTORM(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard)
{
    cout<<"This card destroys ALL magic and traps cards on the field!!"<<endl;
        for (int i=0; i<5; i++)
        {
            Field[3][i]=Card();
        }   
}

void POTOFGREED(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard)
{cout<<" pot of greed"<<endl;}

int main()
{
   // FunctType vector<Card> KaibaDeck(2);
        vector<Card> KaibaDeck(2); //I have no idea what to do here. I just want a Card() vector that can store functions OR have the SetEffect member function be able to take in the HEAVYSTORM and POTOFGREED functions
    //KaibaDeck[0] = HEAVYSTORM;
    //KaibaDeck[1] = POTOFGREED;

    KaibaDeck[0].SetEffect(&HEAVYSTORM);
    KaibaDeck[1].SetEffect(&POTOFGREED);
    KMP(KaibaHand, KaibaDeck, YugiDeck, Field, KaibaGraveyard, YugiGraveyard);
        return 0;
}

Don't get confused! We're doing really well here (though shooting in the dark a bit). Be of good cheer!

Parenthesize (*effect) at line 47, it matters. Otherwise it's trying to call effect() first and then dereference the result (in geek-speek, the argument-passing ()-operator has a higher precedence than the dereferencing *-operator).

And since it looks like it still doesn't know that the types are the same, see if it will let you explicitly cast the function-pointers at lines 69 and 70:

KaibaDeck[0].SetEffect((Card::FunctType*)&HEAVYSTORM);
KaibaDeck[1].SetEffect((Card::FunctType*)&POTOFGREED);

There are a variety of more C++-ish type-casting operators, but I'm woefully ignorant on that particular subject, and this should be sufficient to do what you need! (Fingers crossed!)

Thanks for the help again. The code compiles successfully, but when I start the program, I get a problem after the screen asks for an input number according to the code here

cout<<"enter a number"<<endl;

So if I enter 0 or 1, the program will just crash and stop working.

#include <stdlib.h>
#include <windows.h>
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Card
{ public:

      typedef void (*FunctType)(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard);//, int &KaLP, int &YuLP);
      FunctType* GetEffect() {return Effect;}
      void SetEffect(FunctType* setEffect) {Effect = setEffect; }
      string GetName() {return Name;}
      void SetName(const string& setName) {Name = setName; }

private:
      FunctType* Effect;
      string Name;

};

//typedef void (*FunctType)(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard);

vector<Card> KaibaDeck(40);
vector< vector<Card> > Field(4, vector<Card>(5));
vector<Card> KaibaHand;
vector<Card> KaibaGraveyard;
vector<Card> YugiGraveyard;
vector<Card> YugiDeck;


//void KMP( FunctType* fn )
void KMP(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard)
{
    vector<Card> v1;
    vector<vector<Card> > v2;
    int num;
    cout<<"enter a number"<<endl;
    cin>>num;
KaibaHand.push_back(KaibaDeck[num]);
     Field[0][0]=KaibaHand[0];
Card::FunctType *effect = Field[0][0].GetEffect();// problem here
(*effect) (KaibaHand, KaibaDeck, YugiDeck, Field, KaibaGraveyard, YugiGraveyard);
//must have () on *effect because otherwise the compiler is trying to call effect() first and then dereference the result (the argument-passing ()-operator has a higher precedence than the dereferencing *-operator).
}

void HEAVYSTORM(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard)
{
    cout<<"This card destroys ALL magic and traps cards on the field!!"<<endl;
        for (int i=0; i<5; i++)
        {
            Field[3][i]=Card();
        }   
}

void POTOFGREED(vector<Card> &KaibaHand, vector<Card> &KaibaDeck, vector<Card> &YugiDeck, vector< vector<Card> > &Field, vector<Card> &KaibaGraveyard, vector<Card> &YugiGraveyard)
{cout<<" pot of greed"<<endl;}

int main()
{
   // FunctType vector<Card> KaibaDeck(2);
        vector<Card> KaibaDeck(2); //I have no idea what to do here. I just want a Card() vector that can store functions OR have the SetEffect member function be able to take in the HEAVYSTORM and POTOFGREED functions
    //KaibaDeck[0] = HEAVYSTORM;
    //KaibaDeck[1] = POTOFGREED;

    KaibaDeck[0].SetEffect((Card::FunctType*)&HEAVYSTORM);//(Card::FunctType*)&HEAVYSTORM means to Convert HEAVYSTORM to a FunctType* ?
    KaibaDeck[1].SetEffect((Card::FunctType*)&POTOFGREED);
    KMP(KaibaHand, KaibaDeck, YugiDeck, Field, KaibaGraveyard, YugiGraveyard);
        return 0;
}

Never mind. I got it to work now. The problem was that I did not need all the " * " in

FunctType Effect;
void SetEffect(FunctType setEffect) {Effect = setEffect; }
FunctType GetEffect() {return Effect;}

Thanks for the help!

I don't think the cin is the problem, so insert a pair of lines after line 43, and after each successive line in your KMP() function:

cout << "I got here 1" << endl;
Sleep(1000);  // 1000ms = 1 second

(changing the number each time, so it's obvious how far it gets before it crashes). I -think- the problem is invoking the effect function. Either you're somehow getting a NULL ptr back from GetEffect(), or we're not supposed to dereference the pointer before using it as a function-name. If the former, you can do something like:

if (effect == NULL)
  cout << "error: got NULL effect-pointer for the card" << endl;
else
  (*effect)(args...);

If the latter, try just effect(args...); .

:)

Oops did it again, missed the second page. Good work and happy game-coding!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.