0

I have this error, when I try to use a pointer to member function to a different class.

Error : sources/common/OurMenu.cpp: 
  In member function ‘void OurMenu::menuNavigation()’: sources/common/OurMenu.cpp:336:36: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in 
  ‘((OurMenu*)this)->OurMenu::_buttons.std::vector::at >(((std::vector::size_type)((OurMenu*)this)->OurMenu::_actualLine))->Button::doIt (...)’, e.g. ‘(... ->* ((OurMenu*)this)->OurMenu::_buttons.std::vector::at >(((std::vector::size_type)((OurMenu*)this)->OurMenu::_actualLine))->Button::doIt) (...)’
     _buttons.at(_actualLine)->doIt();

That's my code:

OurMenu.hh

class                           OurMenu
{
 private:
  GraphicLib                    *_window;
  OurGame                       *_game;
  gdl::Geometry                 _background;
  std::vector<gdl::Texture*>    _textures;
  std::vector<Button*>          _buttons;
  int                           _actualLine;
  int                           _time;

public:
  [...]
  void                          menuNavigation();
  void                          gameSetting();
};

Button.hh

class                   Button
{
 private:
  Bloc                  *_select;
  Bloc                  *_notSelect;

 public:
  Button(const float &x, const float &y, gdl::Geometry *back,
     gdl::Texture *tx, gdl::Texture *txS, glm::vec3 const &scale, void (OurMenu::*ptr)());
  ~Button();

  void                  (OurMenu::*doIt)();
  void                  isSelect();
  void                  isDeselect();
  Bloc                  *getSelect() const;
  Bloc                  *getNotSelect() const;
};

Button Declaration

 Button  *solo = new Button(2, 7, &_background, _textures.at(1), _textures.at(7), 
                           glm::vec3(0.0025, 0.0022, 0), &OurMenu::gameSetting);

Function call

solo->doIt();

Button.cpp

Button::Button(const float &x, const float &y, gdl::Geometry *back, 
              gdl::Texture *tx, gdl::Texture *txS, glm::vec3 const &scale, void (OurMenu::*ptr)())
{
  _select = new Bloc(0, 0, back, txS);
  _select->rotate(glm::vec3(1, 1, 0), 180);
  _select->setScale(scale);
  _select->setX(x);
  _select->setY(y);
  _select->setZ(1);

  _notSelect = new Bloc(0, 0, back, tx);
  _notSelect->rotate(glm::vec3(1, 1, 0), 180);
  _notSelect->setScale(scale);
  _notSelect->setX(x);
  _notSelect->setY(y);
  _notSelect->setZ(-1);
  doIt = ptr;
}
MasterAM
  • 16,283
  • 6
  • 45
  • 66
Maxime Limone
  • 121
  • 11

1 Answers1

0

In your case, it looks like you are trying

(solo->doIt)(); // need the parentheses here

where solo is of type Button*, however doIt is a pointer to member function of typevoid (OurMenu::*)(). It won't work, as the pointer to member function must be invoked on an instance of the same type, in your case OurMenu. If solo is cast-able to OurMenu (which is probably not), you can do

(static_cast<OurMenu*>(solo)->doIt)();

Otherwise you should either change your design. It looks like you want to invoke a menu function from your Button instance. If this is so, you need to create an instance of the OurMenu in your Button, and invoke the pointer on that instance, something like

OurMenu menu; // this is created somewhere in Button
(menu.*doIt)();
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • I want to use the doIt function in the Button class but doIt point on a OurMenu function member – Maxime Limone Jun 02 '15 at 15:47
  • You won't be able to do this, unless you can cast a `Button*` to `OurMenu*`. Pointer to member functions cannot be invoked on different object types. – vsoftco Jun 02 '15 at 15:48
  • sources/common/OurMenu.cpp:336:51: error: invalid static_cast from type ‘Button*’ to type ‘OurMenu*’ static_cast(_buttons.at(_actualLine))->doIt(); I have this error when i try your tips – Maxime Limone Jun 02 '15 at 15:51
  • @MaximeLimone yes that's expected, since the types are not related. Think more about your design, why does the pointer to member function has to be of type `void(OurMenu::*)()` but you then invoke it on a `Button` instance? If you know you'll be invoke it on `Button` instances only, change the type of the pointer to member function to `void(Button::*)()`. Otherwise `Button*` itself should be related to `OurMenu*`, so you can cast `Button*` to `OurMenu*` safely; in other words should be derived from, which again doesn't seem to make sense. – vsoftco Jun 02 '15 at 15:52
  • I have a button class when i select a button i want launch the doIt function and in my OurMenu class i have a Button vector and i have too the doIt function like gameSetting for display a new menu – Maxime Limone Jun 02 '15 at 15:53
  • What you need is to create an instance of `OurMenu`, and invoke the `doIt()` on that instance, like `OurMenu menu; (menu.*doIt)();`. I've slightly updated the edit, see if it helps. What you need to understand is that pointer to member functions can only be invoked on instances of the class they are related to. – vsoftco Jun 02 '15 at 15:59
  • Ok so i try that : `(this.*_buttons.at(_actualLine))->doIt();` because i call the do it function in a OurMenu Function member (sorry i didn't give information) _buttons.at(_actualLine) is a Button* – Maxime Limone Jun 02 '15 at 16:03
  • @MaximeLimone as long as what appears before `->doIt)()` is of type `OurMenu*`, it will work. Don't forget the extra set of parentheses, as mentioned in the first line of my answer, and also asked about [here](http://stackoverflow.com/q/12189057/3093378). – vsoftco Jun 02 '15 at 16:04
  • `(this.*_buttons.at(_actualLine))->doIt();`, _buttons.at(_actualLine)) this is a Button* and `this` is a OurMenu instance – Maxime Limone Jun 02 '15 at 16:14
  • @MaximeLimone As I said, if the type is ok, it should work. Just use that extra set of parentheses `( (this.*_buttons.at(_actualLine))->doIt) ();` – vsoftco Jun 02 '15 at 16:16
  • Ok thanks and now i have this error sources/common/OurMenu.cpp: In member function ‘void OurMenu::menuNavigation()’: sources/common/OurMenu.cpp:336:36: error: ‘((OurMenu*)this)->OurMenu::_buttons.std::vector<_Tp, _Alloc>::at – Maxime Limone Jun 02 '15 at 16:22
  • @MaximeLimone As I told you, the compiler is just saying that the type of `(this.*_buttons.at(_actualLine))` **is not** `OurMenu*`. There is nothing you can do here, you **must** invoke the pointer to member function on a `OurMenu` instance. I cannot help you more than that, just try to understand how pointer to member functions work. – vsoftco Jun 02 '15 at 16:24
  • Ok Thank you so much, sorry for my english i'm french ;) – Maxime Limone Jun 02 '15 at 16:26
  • @MaximeLimone No problem, hope the answer helped a bit. – vsoftco Jun 02 '15 at 16:40