7

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)

Jayesh
  • 402
  • 1
  • 4
  • 22
  • 4
    First, this isn't C++. Second, it makes absolutely no sense to access some per-object variable with no object. – chris Nov 14 '14 at 12:32
  • Sorry chris, but I am actually a Java programmer that's why I made the mistake, I'll update the code sample. Thanks for pointing it out. – Jayesh Nov 14 '14 at 12:33
  • In a static function, there is no "current instance". That's what static means. If you want there to be an instance, either drop the `static`, or pass one to the function in some other manner. – Mike Seymour Nov 14 '14 at 12:35
  • @chris Actually I want to access the T2 at that place, but couldn't find a solution for the same. Can you please help. – Jayesh Nov 14 '14 at 12:36
  • @Jayesh: The T2 at what place? Without an object, you simply can't access an object. The question makes no sense whatsoever. – Mike Seymour Nov 14 '14 at 12:36
  • @MikeSeymour The SDK that I am using doesn't allow me to drop static nor allows me to pass it in argument list, as this function is of pre-defined format kind. Can you please suggest an alternate? – Jayesh Nov 14 '14 at 12:38
  • @Jayesh: Either use a less broken SDK - a well-designed callback type should take a "user data" parameter for this kind of situation - or put an instance somewhere accessible from the function (perhaps a static class member) and take great care not to overwrite it while the function might still need it. – Mike Seymour Nov 14 '14 at 12:41

4 Answers4

3

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.

Community
  • 1
  • 1
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • If it wants a function pointer, then you can't give it a `bind` result; that's a class type, containing the bound values, so not convertible to a simple function pointer. There's no way to pass extra state if it only takes a function pointer. – Mike Seymour Nov 14 '14 at 15:21
  • @MikeSeymour It depends on the parameter type. For example Qt's slots accept a `std:function` type, which will accept the output of `std::bind`. I suspect that is what [Jayesh](http://stackoverflow.com/users/1093333/jayesh) was using his function for. – Jonathan Mee Nov 14 '14 at 16:10
  • Indeed, if the parameter type is `std::function` or similar, then it will accept any callable object. But if it wants a function pointer, then you can't use `bind`, contrary to the final sentence of your answer. – Mike Seymour Nov 14 '14 at 16:14
  • @MikeSeymour I've edited the answer for the sake of correctness. – Jonathan Mee Nov 14 '14 at 16:27
0

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.

Community
  • 1
  • 1
John
  • 6,433
  • 7
  • 47
  • 82
0

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();});
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
0

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