Jayesh
Jayesh

Reputation: 437

Calling non-static variable from static function

I am a beginner programmer in C++ and doing a PoC for my company. So I apologize for my basic question.

class TestOne{
  private:
    TestTwo* t2;

  void createInstance(TestTwo* param){
    t2 = param;
  }

  static void staticFunctionToAccessT2(){
    // Now here I want to access "t2" here in the current instance of the class
    // By current instance I mean "this" in non-static context
    // currently there is no function to get object, but can be created
    // ** we cannot call new TestOne(), because that will create a new instance
    // ** of the current class and that I don't want.
  }
}

Any help in this regard will be greatly appreciated.

Thanks

===UPDATE===

This can be taken as a scenario in which I am developing an application in QT Creator, where I have a static function of predefined signature and want to access the UI elements for text change(like TextEdit)

Upvotes: 7

Views: 28404

Answers (4)

Vikash Mohapatra
Vikash Mohapatra

Reputation: 1

There is possibly a way to set the non static variable member of a class using a static function call, but this can be done when you pass the reference of the same class to the static function and access the non static function to set the not static member variable. But again there is no good reason why someone needs to do this. May be just for interview perspective I could definitely say there is a way for doing it Find the below code snippet doing the same:

#include <iostream>
using namespace std;
class Test{
    int x;
    static int y;
    public:
        static void setY(int val){
            y = val;
        }
        void setX(int val){
            x = val;
        }
        static void setXY(int xval,int yval, Test& obj){
          obj.setX(xval);
            y = yval;
        }
        void display(){
            cout<<"x : "<<x<<", y: "<<y<<endl;
        }
};

int Test::y = 0;
int main()
{
    Test t;
    t.setY(10);
    t.setX(1);
    t.display();
    
    Test t1;
    t1.setX(100);
    t1.display();
    
    t1.setXY(1000,2000,t1);
    t1.display();


    return 0;
}

Output from the above code execution : x : 1, y: 10 x : 100, y: 10 x : 1000, y: 2000

Code Snippet along with output : Code_Snippet_With_Output

Upvotes: 0

Jonathan Mee
Jonathan Mee

Reputation: 38919

You can't do this, even in Java.

static methods are simply local helper functions for all instances of the class with no access to individual class state (for example t2).

Either remove the static from the method, or make the member variable a static variable, depending on what you are trying to accomplish.

EDIT:

If I understand you correctly your SDK wants a function pointer which it will call to modify your instances' t2. Your mutator method should be public and non-static. So let's just say you redefined staticFunctionToAccessT2 like this:

public: void mutateT2();

If the instance you wanted to call mutateT2 on was defined as:

TestOne foo;

Where your SDK wants a function pointer you could pass this in:

std::bind(&TestOne::mutateT2, foo)

As is pointed out by Mike Seymour below this only works if the SDK method parameter is a std::function not if its parameter is a raw function pointer.

Upvotes: 3

Mike Seymour
Mike Seymour

Reputation: 254431

There is no "current instance"; you can't access non-static members from a static function without access to some instance somewhere.

From your comments, it seems that you're using a broken API with a callback (or similar) mechanism that doesn't pass user data to the function you provide. In that case, you'll have to find some other way to get data to the function; perhaps a static member:

static TestOne * bodge;
static void staticFunctionToAccessT2(){
    TestTwo * t2 = bodge->t2;
}

so the API can be used thusly

TestOne::bodge = my_t1;
broken_api(&TestOne::staticFunctionToAccessT2);

Be careful not to set bodge to some other value until the API has finished whatever it's doing with your callback.

A less broken API would define a callback type that can take a "user data" parameter; perhaps a void* pointer, which can point to arbitrary data. You can use that thusly:

static void staticFunctionToAccessT2(void * p) {
    TestOne * t1 = static_cast<TestOne*>(p);
    TestTwo * t2 = t1->t2;
}

less_broken_api(&TestOne::staticFunctionToAccessT2, my_t1);

A nice modern API would accept arbitrary callable types, so you could use a non-static function:

void memberFunctionToAccessT2() {
    TestTwo * t2 = this->t2;
}

nice_api([=]{my_t1->memberFunctionToAccessT2();});

Upvotes: 0

John
John

Reputation: 6648

A static member function has no "current instance".

If you want to limit your class to having only one instance you are looking for the Singleton design (anti-)pattern, Singleton pattern in C++. It's actually not that evil and I always feel an attraction to it whenever I am working with classes having static member variables.

There are a number of approaches to making the singleton work better, close attention to RAII should be your driving goal here and I use std::unique_ptr<TestOne> safeInstance; while I'm initialising in my getInstance() static method, in the absence of exceptions in my Android environment.

I generally would urge you not to use the Singleton Pattern if you have insufficent experience to need to ask this question. But it seems to address most of the issues in your question.

Additionaly, to call non-static "variable", I assume you meant "method", your static function must work with your singleton instance, assuming it was created successfully that is. It can even access non-static variable through the singleton instance.

Upvotes: 0

Related Questions