-1

headerfile.h

class A
{
  cv::Mat depthimagemouse;
  std::string m_winname;

public:

  A(const std::string &winname, const cv::Mat depth_clean);
  static void onMouse( int evt, int x, int y, int flags, void* param );
};

cppfile.cpp

A::A(const std::string &winname, const cv::Mat depth_clean)
    : m_winname(winname), depthimagemouse(depth_clean)
{
//something..
}

void A::onMouse( int event, int x, int y, int flags, void* param )
{
//Here I want to use depthimagemouse member variable (and other members..)
}

My question is how can I use depthimagemouse variable in onMouse method?

Ja_cpp
  • 2,426
  • 7
  • 27
  • 49
  • Since `onMouse` is static, it should(i am not sure about can) not access non static members. – Gaurav Sehgal Jun 27 '16 at 09:56
  • You want something exactly opposite than in your title: you want to access member from static method. And it's impossible. – MaciekGrynda Jun 27 '16 at 09:57
  • I know! that's my question as I must declare `onMouse` as static to remove its `this` pointer – Ja_cpp Jun 27 '16 at 09:58
  • 1
    The people saying you can't access non-static members within a static method are talking nonsense. Static methods have fully privileged access to all class members of any instance, so long as they know which instance to use, through a `this` pointer/reference. Many libraries provision callbacks with 'user data' pointers that can be used for this purpose. – underscore_d Jun 27 '16 at 09:58
  • @underscore_d yes, you can do that, but why declare method as static then? – MaciekGrynda Jun 27 '16 at 10:00
  • 1
    @MaciekGrynda e.g. if you are using a callback mechanism that does not directly support member functions, a static function is required to provide a compatible function signature. Like the OP is, here, with OpenCV, in this repeat of a previous thread in which they were already told all of this. – underscore_d Jun 27 '16 at 10:01
  • @MaciekGrynda I must declare it as static to remove its `this` pointer so as I can pass a pointer-to-member-function to setMouseCallback in OpenCV – Ja_cpp Jun 27 '16 at 10:01

3 Answers3

3

I'd be surprised if the library didn't explain this somewhere in its documentation, but anyway. This is standard procedure when you're using callbacks that don't support member functions, but you still need a way to access member data. So, you do the following:

  • Pass a reference to the instance as your user data pointer param (or a member thereof) when registering the callback.
  • Cast this back to the concrete type to access its members. A class static function has full access to all members of its class, via a provided instance.

So, you can do it this way:

auto &that = *static_cast<A *>(param); // <= C++03: use A &that
// Cast to const A if you want, or use a pointer, or etc.
std::cout << that.depthimagemouse << std::endl;

Or it's often nicer syntactically to immediately despatch to a member function and let it do everything:

static_cast<A *>(param)->doRestOfStuff(evt, x, y, flags);
// Include a const in the cast if the method is const

Or anywhere in between.

underscore_d
  • 6,309
  • 3
  • 38
  • 64
  • The issue is that my compiler doesn't support C++11 (it seems!) But @Jean-Baptiste Yunès solution works fine – Ja_cpp Jun 27 '16 at 11:33
  • It says error: ISO C++ forbids declaration of ‘ ’ with no type when I use `auto` And I didn't say that you're wrong I just use it without `auto` – Ja_cpp Jun 27 '16 at 13:38
  • @RosCpp Ohhh, sorry, I forgot about the`auto` and didn't notice it when I reviewed the post... it's just a habit that I don't even think about! Thanks for letting me know, and I've added a note about that. It's funny, actually: `auto` usually saves typing, but for this example `class A`, it makes things worse in that sense ;-) The power of habits... – underscore_d Jun 27 '16 at 13:41
0

depthimagemouse is an instance member, means that each A instance (object if you prefer) has its own depthimagemouse. Your onMouse method is a static one, means that it is not related to any particular given instance but to all instances, and thus it's nonsense to think about accessing depthimagemouse without specifying which instance you are interested in.

Without any more information about onMouse and your model it is hard to tell you what to do. May be param can be used to specify an instance of A that the static method will receive? In that case, a cast can be used to get the instance back inside the method: A *anInstance = static_cast<A *>(param); with which you can then play: anInstance->depthimagemouse (see that we are talking about the depthimagemouse of a given instance?), etc.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
0

make depthimagemouse as global variable can achieve, but need intialize it in a specialized method. here is one implementation

global.h

extern cv::Mat depthimagemouse;

global.cpp

cv::Mat depthimagemouse;

headerfile.h

#include "global.h"

class A
{
  std::string m_winname;

public:

  A(const std::string &winname);
  void init(const cv::Mat depthimagemouse_) {depthimagemouse = depthimagemouse_};
  static void onMouse( int evt, int x, int y, int flags, void* param );
};

cppfile.cpp

A::A(const std::string &winname)
: m_winname(winname)
{
//something..
}

void A::onMouse( int event, int x, int y, int flags, void* param )
{
  //use depthimagemouse
}