0

I have a class that has a few static functions that can be called even if there is no instance of that class. There is also a method init() that I use to set some variables. This method is not static thus it needs an instance. Now if this was done I want the static methods to behave differently. Sort of like:

static foo(){
  if(noInstance()){
    doA();
  }else(){
    doB();
  }
}

Is this even possible? Or a bad idea and should just make the user call different methods if there is an instance? Thanks

EDIT It sounds weird but this is my use case:

class A{

public:
    static inline bool hasInstance = false;
    int data;

static int getData(){
    if(hasInstance){
        return data; // Can't do this from a static function
    }else{
        return 0;
    }
}

};

I know that I cant access the data from a static function beacuse there is no this pointer. I'm coding a library and I want the user to be able to use the static method if he dosen't want an instance but if there is an instance it should make use of the data of its instance.

If had an idea but I don't know wether that's good style:

static int getData(A *ref){
    if(ref != nullptr){
        return data;
    }else{
        return 0;
    }
}

I'd glad to hear from someone with more experience wether I should do that.

4
  • Did you consider using a simple reference counter, updated by the class's constructors and destructor (don't forget a copy constructor)? Check the reference count. If there are multiple execution threads, some thread-related consideration need to be addressed. Commented Jun 19, 2020 at 12:29
  • @ΦXocę웃Пepeúpaツ Do you mean if(this == nullptr) ? I can not check from outside. It need to be in that static method. Commented Jun 19, 2020 at 12:31
  • @SamVarshavchik I've looked up ways to do reference counting. Which way do you recommend? Should I just have some plan int that I increment? Using some fancy shared_ptr stuff would limit the usability of my class I suppose. Commented Jun 19, 2020 at 12:36
  • 1
    you dont need full blown reference counting, only simpler "instance counting". A plain int that counts the existing instances is sufficient, just take care of copies, etc Commented Jun 19, 2020 at 12:41

3 Answers 3

4

I think you can use a static variable, let it be named count. You initialize count with 0, and every time you create an instance of that class, you increment count. If count is 0, that means you did not created any instance, therefore you can't use some methods.

Sign up to request clarification or add additional context in comments.

6 Comments

Going to try that! Thanks
The problem i've stepped on now is that i cannot initialize the counter variable as 0 in the class. Apparently you can only set non-const static variables from the outside. this defies the purpose of what I was trying to do. I want the user to be able to use the method without any initialization before the actual use. What do I do?
@SchnJulian It would still be the class author who initializes it, not the user, even if it's technically defined outside the class. Still, if you're using c++17, you can make the variable inline, and initialize it inside the class.
@cigien at the moment I'm trying to do what i want to do with an object reference that is either null or the object whose members I'm accessing. cause even if I could check wether there is an instance or not it still wouldnt be able to access the non static member from the static functions without an object as parameter.
@SchnJulian Hmm, then go ahead and make a separate question for this particular problem you are facing.
|
1

I'm coding a library and I want the user to be able to use the static method if he dosen't want an instance but if there is an instance it should make use of the data of its instance.

In general, free functions are recommended rather than member functions (gotw). It is actually rare to have good reasons to make a static function a member function. It would need to be a member if it would need access to privates of the class, but that doesnt seem to be the case here and then it still could be a friend function.

Let's look at your approach:

static int getData(A *ref){
    if(ref != nullptr){
        return data;
    }else{
        return 0;
    }
}

You probably meant to write ref->data;, also I guess you are not merely returning the value of the member. That would be of little use, because If I have an instance I can get my hands on x.data without needing to call getData. And I suppose 0 is just a placeholder for someother value that you have there in the real code.

I am going a bit subjective now...

If I was a user of your library, I would want to know if getData returns data from one of the objects I did create or something else. Having one and the same function that does both would confuse me. I don't like pointers and I am scared of nullpointers, so if you force me to write

getData(nullptr);

this would not make me happy. I would like to have two different functions:

int getData() { return 0; }
int getData(const A& x) { return x.data; }

If I have no instance, I can call the first, if I have one I can call the second.

1 Comment

Thanks a lot! That is really helpful :)
0

Not sure what is your final goal, but I would recommend reconsidering your design, because this static/hasInstance behavior smells. Anyway, here is what you need:

using namespace std;

#include <iostream>

class MyClass
{
private:
    static bool hasInstance;
public:
    MyClass()
    {
        hasInstance = true;
    }

    static void foo()
    {
        if (hasInstance) {
            std::cout << "I have an instance\n";
        }
        else {
            std::cout << "No instance\n";
        }
    }
};

bool MyClass::hasInstance = false;

int main () {
    MyClass::foo();
    MyClass a;
    a.foo();
    MyClass::foo();
    return 0;
}

EDIT: Don't use it in real code. If you just curious, you can do almost everything in C++, so you could pass the object sometimes, it's dirty and ugly, but just for the demo: using namespace std;

#include <iostream>

class MyClass
{
private:
    int someVariable;
public:
    MyClass()
    {
        someVariable = 42;
    }

    static void foo(MyClass *obj = nullptr)
    {
        if (obj) {
            std::cout << obj->someVariable << std::endl;
        }
        else {
            std::cout << "No instance\n";
        }
    }
};

int main () {
    MyClass::foo();
    MyClass a;
    a.foo(&a);
    MyClass::foo(&a);
    return 0;
}

4 Comments

Thanks. Where do I put the bool MyClass::hasInstance = false; statement in my code?
The problem I was trying to avoid is when in your code it says "I have an instance" I wanna access non-static member variables. Like "I have an instance and this is my data: " but I cant access this data from a static function.
Shortly: you can't access non-static data from a static function, because it doesn't have this pointer, right? So maybe you should create a separate question describing in more detail what you want to implement and the community will be able to find a more suitable approach.
I've edited my answer just to demonstrate how you can do it, but you SHOUDN'T do it this way. There are definitely many other better ways to approach your problem.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.