'How static function is accessing private member function(constructor) of a class

I came across code like the below, which is basically an example of a singleton class in which we make the class constructor private and provide one static public function to create an instance of the class when required.

My question is when we call the new operator to create an object of the singleton class inside the static function, then the constructor of the class will surely be called. I am confused how it happens because, as far I know, a static function can only access static members and static functions of a class then how can it access a private function (i.e. the constructor in this case) of a class?

Can a static function call any private or public member function of class without creating any instance?

#include <iostream>

using namespace std;

class Singleton
{
public:
    static Singleton *getInstance(); 

private:
    Singleton(){}
    static Singleton* instance;
};

Singleton* Singleton::instance = 0;
Singleton* Singleton::getInstance() 
{
    if(!instance) {
        instance = new Singleton(); //private ctor will be called
        cout << "getInstance(): First instance\n";
        return instance;
    }
    else {
        cout << "getInstance(): previous instance\n";
        return instance;
    }
}

int main()
{
    Singleton *s1 = Singleton::getInstance();
    Singleton *s2 = Singleton::getInstance();
    return 0;
}

But when I wrote a sample code as below:

class Sample
{
    private:
        void testFunc()
        {
            std::cout << "Inside private function" <<std::endl;
        }
    public:
        static void statFunc()
        {
            std::cout << "Inside static function" <<std::endl;
            testFunc();
        }
};

int main()
{
    Sample::statFunc();

    return 0;
}

I get a compilation error with g++ :

file.cpp: In static member function ‘static void Sample::statFunc()’:
file.cpp:61: error: cannot call member function ‘void Sample::testFunc()’ without object. 

If we can access private function of class with static public function then why i am getting this error?



Solution 1:[1]

The reason the above code works is because the implementation of getInstance() calls the constructor which does not requrire an instance of the object.

Static member functions belong to the class not the object. Hence there is no instance of an object when calling a static member function, you cannot access the this pointer becuase there isn't one. If you want to access non-static private member functions from a static function the reference of the object needs to be passed to the function. e.g.

e.g.

class foo {
    public:
          foo(int i) : myInt(i) {}
          static int myStaticMethod(foo & obj);
    private:
          int myInt;
    };

    int foo::myStaticMethod(foo & obj) {
          return obj.myInt;
    }

#include <iostream>


int main() {
foo f(1);
std::cout << foo::myStaticMethod(f);
return 0;
};

Solution 2:[2]

Can a static function call any private or public member function of class without creating any instance?

You are creating an instance.

instance = new Singleton();

The new keyword creates a Singleton object.

And, yes, because Singleton::getInstance is a member function of the class, it has the ability to invoke the constructor (though note you're doing so only indirectly), whether it's static or not.

Solution 3:[3]

Answer for the second part of your question that you have added later:

class Sample
{
private:
  void testFunc()
  {
    std::cout << "Inside private function" << std::endl;
  }
public:
  static void statFunc()
  {
    std::cout << "Inside static function" << std::endl;

    Sample s;
    s.testFunc();          // this is OK, there is an object (s) and we call 
                           // testFunc upon s

    // testFunc();         // this is not OK, there is no object
  }
  void InstanceFunction()
  {
    std::cout << "Inside public instance function" << std::endl;
    testFunc();
  }
};


int main()
{
  Sample s;
  s.InstanceFunction();

  Sample::statFunc();
  return 0;
}

Calling testFunc(); from inside statFunc cannot be done, because testFunc (private or not) is an instance function, you need a Sample object that testFunc can operate upon, but statFunc is a static function, therefore there is no Sample object.

The error message is pretty clear about that.

You can call testFunc from statFunc only if you provide an object, see code above.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 TomJ
Solution 2 Lightness Races in Orbit
Solution 3