2

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?

Jack
  • 694
  • 8
  • 20
  • Short answer: IMHO yes. And IMHO there is no problem with your code. `getInstance` is a member of the `Singleton` class, therefore it can call all methods of the class, even private ones. – Jabberwocky Nov 21 '16 at 13:52

3 Answers3

1

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.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
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;
};
TomJ
  • 424
  • 3
  • 14
  • Thanks for your answer. So what i understood from above is that as ctor is a special member function which does not require any object to be called upon so it can be called using static function(without any object) but other normal member functions of a class need class instance in order to call them so they can not be called inside static function without object. – Jack Nov 22 '16 at 06:01
  • Yeah pretty much – TomJ Nov 22 '16 at 09:07
0

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.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • What I think is that in a similar way the contructor of singleton class is a class function and shall not be called by static function.If construtor can get called inside static function then why not the normal private function is what confusing me? – Jack Nov 21 '16 at 14:20
  • @Vikram remember, a constructor is not a normal member funtion. When you write `instance = new Singleton();` you _are_ creating an object, and he constructor is called upon the object that is being created. – Jabberwocky Nov 21 '16 at 14:24
  • @Vikram, I've edited the answer, now there is an example how you can call `testFunc` from within `statFunc`. – Jabberwocky Nov 21 '16 at 14:32