Reputation: 81
I am trying to implement singleton that I have used before in PHP and Java 8, to C++. But I do face certain restrictions from the syntax and how C++ works (specifically pointers).
This is what I have tried so far:
#include "iostream"
using namespace std;
class System{
protected:
static System *obj;
public:
static System *getInstance(){
return obj;
}
void prn(){
cout<<"this works!";
}
};
int main(void){
System &sys = System::getInstance();
sys.prn();
}
while executing, I get the following error:
sameer.cpp:20:10: error: non-const lvalue reference to type 'System'
cannot bind
to a temporary of type 'System *'
System &sys = System::getInstance();
^ ~~~~~~~~~~~~~~~~~~~~~
Please help me solve this error.. as I have no idea what it means. I have checked the forum before posting, and it can be a possible duplicate of previously asked question (which I caould not find).. But I posted this because I wanted to understand the meaning of error my code generated.
Thanks for the help
Upvotes: 3
Views: 27691
Reputation: 1103
It might be good to lazy-initialize your singleton. Also, consider making the constructor and the singleton private so you can't create an instance anywhere else.
#include <iostream>
class System
{
private:
static System *obj;
System() {}
public:
static System& getInstance(){
if (nullptr == obj)
obj = new System();
return obj;
}
void prn(){
std::cout << "this works!";
}
};
int main(void){
System& sys = System::getInstance();
sys.prn();
}
Upvotes: -1
Reputation: 59
#include <iostream>
using namespace std;
class System{
private:
static System *obj;
System() {}
public:
static System *getInstance()
{
if(obj == nullptr)
obj = new System();
return obj;
}
void prn(){
cout<<"this works!"<< endl;
}
};
System *System::obj;
int main(void){
System *sys = System::getInstance();
sys->prn();
}
Upvotes: 3
Reputation: 16824
In C++, references and pointers are different things. A reference behaves exactly like the original variable, whereas a pointer represents the memory address of that variable. You're getting the error because you're trying to assign a pointer-to-System
to a variable of type reference-to-System
, which isn't the same thing. If you really wanted to you could dereference the pointer by using the System& sys = *ptr;
syntax, but in this case that's the wrong thing to do; the correct fix is to return a reference from your getInstance()
function, rather than a pointer.
What's more, in C++ you can actually store the static
instance variable within the getInstance()
function. This is a so-called "magic static", otherwise known as a "Meyers Singleton", and since C++11 it guarantees you get thread-safe construction of the singleton object. So the final solution would be:
class System
{
private:
System() {}
public:
static System& getInstance(){
static System theInstance;
return theInstance;
}
void prn(){
cout<<"this works!";
}
};
int main()
{
System& sys = System::getInstance();
sys.prn();
}
Also, as an aside, you should use
#include <iostream>
not
#include "iostream"
to include standard library headers. And you don't need to say main(void)
in C++; empty brackets signify that a function takes no arguments, so main()
will do.
Upvotes: 17
Reputation: 72271
getInstance()
returns a pointer, but you are trying to call it and bind it to a reference. If you want it to return a reference, make it return a reference.
static System &getInstance(){
return *obj;
}
Upvotes: 2