tags:

views:

1755

answers:

8

Is it possible to call a non-static data member in a static member function? And is it also possible to call a non-static member function in a static member function?

How do you do it?

+2  A: 

You will need some existing object to call its non-static member function or access its non-static data member.

epatel
If the call is non-virtual and the method doesn't access data members you really don't need an object - null pointer would be enough.
sharptooth
Sure, C++ is a minefield :) ...or one can create a local object as others are suggesting
epatel
@sharptooth: Nope - calling any fucntion will a null pointer is illegal. Besides, you still managed to miss at least one case: calling a non-virtual function which in turns calls a virtual function. That will certainly blow up.
MSalters
A: 

Not normally, unless you have a static pointer to an instance.

The problem is that the static method doesn't have a particular instance on which it's working. You can call the non-static member function if you pass in the instance, but otherwise, no.

Reed Copsey
+2  A: 

You need an instance to the object in order to call a non-static member function or access a non-static data member. Statics don't have that, so in general they can't, unless they got one from somewhere (i.e., you have a global table that the static function uses to get a pointer to the object.)

But statics are not supposed to access non-static data . . . if they have to, they shouldn't be static. Can you show us what you are trying to do?

Michael
A: 

No, thats not possible unless you can somehow gain access to an instance of the defining class.

m0rb
A: 

Yes to both:

class A {

   int x;

   void f() {
      staticfunc(); 
   }

   static void staticfunc() {
      A a;
      a.x = 42;
      a.f();
   }
};

Of course the mutual recursion in the above will cause a few problems :-)

anon
+5  A: 

YES - you can, and here is how

class Foo
{
    public:
     static void staticFunc( const Foo &  foo)
     {
           foo.memberFunc();      

     }
      void memberFunc() const
      {
           staticFunc(*this);

      } 


};

This is the sort of a design, recursion aside, demonstrates how to call both static and non-static member functions.

Cant do that -- you are passing a const reference to your static, the member function has to be const.
dirkgently
Just what I need.. Thanks
cool, now you can accept it :)
I changed the implementation to the original version. hope it helps
There's a lot more to member access and signatures. See below ;)
dirkgently
But what's the point? staticFunc() is just a nonstatic member function in disguise, with a more awkward calling syntax.
Pontus Gagge
I am sure he has a use that requires this sort of functionality (I am curious too). As for my example, I've stated that it is for demonstrative purposes only.
MSalters
+1  A: 

Since people are hell-bent on downvoting, here is the summary:

You can access a non-static member from within a static member function provided you pass in a class instance, OR a pointer thereof OR a reference. The object's qualification (in other words, the static member signature) will determine whether you can call only const or both const and non-const member functions from within.

Non-static member data/functions rely on the this pointer -- which is basically a pointer to the object accessing/invoking the member data/function. Statics are class level and are not associated with the individual objects. If, however, you pass on a reference/pointer of a class instance/or an instance itself to the static function, you can make a call.

#include <iostream>
struct Eg {
 Eg() : x(42), y(-42) {}

static void foo(Eg const&f) {
    std::cout << "foo\n";
    f.bar();

    // we are good -- x is mutable
    std::cout << f.x << std::endl;
    f.x = 24;
    std::cout << f.x << std::endl;

    std::cout << f.y << std::endl;

    // you need non-const access for the following
    // so they don't work -- see foo signature
    //f.y = -24; compile error -- const l-value    

   // f.barbar(); same as above
}

void bar() const { // const required since we have a const reference
 std::cout << "bar\n";
}

void barbar() { // const required since we have a const reference
 std::cout << "bar\n";
}

  // note well the members
  mutable int x;
  int y;
};

int main() {
   Eg ex;

   Eg::foo(ex); // or ex.foo(ex);
}

Look at the Singleton/factory method pattern -- they'll be of interest to you.

dirkgently
A: 

The typical use case for this would be handing off C API callbacks to object instances in a C++ project.

 // declared in some external C API
typedef void __stdcall EnumDataCallback( void* context, void* data );
void EnumData( EnumDataCallback* callback, void* context ); 

// in consuming C++ Project
class MyDataManager
{
public:
  void PollData()
  {
       ::EnumData( &MyObject::StaticEnumData, this );
  }
private:
  static void __stdcall StaticEnumData( void* context, void* data )
  {
    MyDataManager* instance = (MyDataManager*)(context);
    instance->EnumData( data );
  }
  void EnumData( void* data )
  {
    // actual callback code
  }
};