So I've been working on my what I thought would be quick and easy project for a couple hours now and I can't get it to work! It's making me frustrated lol I've got to be close, but maybe I'm not.
I'll include my code with comments explaining what it should be doing. Essentially its using a private constructor and destructor. A member integer and then a public static function to return a reference to an object in the class - and a public function that should display the member integer and increment it. I keep getting scope and initialization errors.
HERES THE ERRORS:
Singleton.h: In function ‘int main(int, char**)’:
Singleton.h:28:2: error: ‘Singleton::Singleton()’ is private
main.cpp:38:12: error: within this context
Singleton.h:29:2: error: ‘Singleton::~Singleton()’ is private
main.cpp:38:12: error: within this context
Any help or suggestions will be greatly appreciated!
Heres my code (Singleton.h, Singleton.cpp, main.cpp):
Singleton.h :
#ifndef SINGLETON_H
#define SINGLETON_H
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
class Singleton {
public:
static Singleton& instance(); //returns a reference to a Singleton obj
void sendOutput(); //prints member variable and increments it
private:
int myInt; //member integer-variable
Singleton(); //constructor
~Singleton(); //destructor
};
#endif
Singleton.cpp :
#include <string>
#include "Singleton.h"
using namespace std;
//Displays to console that the obj was created. Initializes the member variable
Singleton::Singleton(){
myInt = 0; //member variable
cout << "Singleton Object Created!" << endl;
}
//destructor - displays to console that the Singleton object was destructed
Singleton::~Singleton(){
// delete myObj;
cout << "Singleton Object Destructed!" << endl;
}
//display member variable value and increment
void Singleton::sendOutput(){
cout << "Request to send data to output to console" << endl;
cout << "Integer Value: " << myInt << endl;
myInt++;
}
//REQUIRED: Static method with a reference to an object of this class return type
//create a static Singleton object and return it
Singleton& Singleton::instance(){
static Singleton myObj;
return myObj;
}
main.cpp :
#include "Singleton.h"
#include <string>
#include <iostream>
#include <cstdlib>
using namespace std;
//Another requirement - demo static variables
void static_test(){
static int a = 1;
cout << a << endl;
a++;
}
int main(int argc, char * argv[]){
static_test();
static_test();
static_test();
//messed around with this for awhile - got it to work a few times
//messed it up a few more times O.o
Singleton mySingletonObj;
Singleton& sRef = Singleton::instance();
//sRef = Singleton::instance();
sRef.sendOutput();
return 0;
}
Thought/Suggestions/Questions/Concerns?
Anything will help relieve the frustration this has been causing me lol. It seems too simple to be causing me such a problem. Thanks!
Forbidden in that scope:
Singleton mySingletonObj;
Should be OK:
Singleton& sRef = Singleton::instance();
References are not reassignable:
sRef = Singleton::instance();
Should be OK:
sRef.sendOutput();
Also, remove this -- the language already specifies the lifetime and storage of the object, and takes care of destructing it:
delete myObj;
You should also delete the ability to copy the type:
Singleton(); //constructor
Singleton(const Singleton&) = delete; // deleted copy constructor
Just remove delete myObj; here:
Singleton::~Singleton(){
delete myObj;
cout << "Singleton Object Destructed!" << endl;
}
and it should work. myObj is statically allocated so will be deleted by runtime on process exit.
First of all you should understand basics of the language before yo start writing programs on it. From your code looks like you try to delete myObj, which is local static object from another method and not visible in destructor, not to mention that you can call delete only on pointers and should delete only pointers initialized by operator new.
Also your singleton should have private or deleted (for C++11) copy constructor and assignment operator. If you do that line: "sRef = Singleton::instance();" will not compile (and it should not logically). Other than that everything is fine.
Related
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
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.
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;
}
#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();
}
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();
}
Not sure how correctly formulate the question but here is the problem.
I have a static lib where I have the following class in a.h:
#pragma once
#include <vector>
class A{
public:
void Run() {
data_.push_back(10);
std::cout << "size: " << data_.size() << std::endl;
}
private:
static std::vector<int> data_;
};
a.cpp is as follows:
#include "a.h"
std::vector<int> A::data_;
And I have another class in b.h:
#pragma once
#include <string>
class B
{
public:
static std::string Get();
};
And b.cpp:
#include "b.h"
#include "a.h"
std::string B::Get()
{
static A a;
a.Run();
return "foo";
}
Now my main app which is using the above static lib is as follows:
#include <iostream>
#include "a.h"
#include "b.h"
static std::string var1= B::Get();
int main(int argc, char** argv)
{
A a;
a.Run();
}
Trying to understand why the output is:
size: 1
size: 1
There should be a single instance of each static data member for the entire class, so there should be a single call to A::data_ constructor.
Am I hitting "static initialization order fiasco"? I.e. data_ is not initialised before I use it, but then I should be getting the crash?
And now lets imagine my data_ holds dynamically initialised items (something none POD). How will it be destructed if at the end data_ holds one item, although I've inserted 2?
And that's what actually is happening in my real life code (it sometimes crashes during destruction of data_).
Getting rid of global static ( static std::string var1= B::Get(); ) solves the problem, but I still want to understand the under the hood problem.
The described case can be reproduced in VS2015 (the real life case is reproducible in gcc 6.2 )
Am I hitting "static initialization order fiasco"?
Most likely.
You can remove the problem by making the static data of a class available via a function call. E.g.
class A{
public:
void Run() {
getData().push_back(10);
std::cout << "size: " << getData().size() << std::endl;
}
private:
static std::vector<int>& getData();
};
std::vector<int>& A::getData()
{
static std::vector<int> data;
return data;
}
When you do that, data will be initialized when A::getData() is called the first time. It removes the static initialization order issue completely.
in c++, whats the difference between writing something like
myclass myobject();
//and
myclass myobject;
also i'm new to stack overflow so if i'm doing something wrong just tell me.
When you write:
myclass myobject();
You may think you're creating a new object of type myclass, but you actually declared a function called myobject, that takes no parameters, and has a return-type of myclass.
If you want to see that for sure, check this code:
#include <stdio.h>
#include <iostream>
using namespace std;
class myclass
{ public: int ReturnFive() { return 5; } };
int main(void) {
myclass myObjectA;
myclass myObjectB(); // Does NOT declare an object
cout << myObjectA.ReturnFive() << endl; // Uses ObjectA
cout << myObjectB.ReturnFive() << endl; // Causes a compiler error!
return 0;
}
prog.cpp: In function ‘int main()’:
prog.cpp:18:23: error: request for member ‘ReturnFive’ in ‘myObjectB’, which is of non-class type ‘myclass()’
cout << myObjectB.ReturnFive() << endl;
^~~~~~~~~~
The difference is same as,
int a; and int a();
I am pretty sure that you understand now. Just for the sake of answer, I am explaining it below.
int a; // -> a is a variable of type int
int a(); // -> a is a function returning int with void paramters
I have a problem with static members of a class not being initialized before the constructor. Am i doing something wrong? Is it a bug in G++ ?
Any workarounds?
g++ --version : (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
I am also using Eclipse as my IDE, but i just copy the static lib headers to /usr/include/StaticTestLib/InitTest.h and the library to /usr/lib/x86_64-linux-gnu/libStaticTestLib.a
Note this only happens if the object that holds the data is defined before main and the class is in a Static Library.
Static library header (the static library itself is named StaticTestLib):
InitTest.h
#include <iostream>
namespace StaticTestLib {
class notifier_header{
public:
notifier_header(){
std::cout<<"static var init"<<std::endl;
}
};
class InitTest {
public:
static notifier_header _header_notifier;
InitTest();
virtual ~InitTest();
};
}
Static library source file:
InitTest.cpp
#include "InitTest.h"
namespace StaticTestLib {
notifier_header InitTest::_header_notifier;
class notifier_cpp{
public:
notifier_cpp(){
std::cout<<"code before constructor"<<std::endl;
}
}_notifier_in_cpp;
InitTest::InitTest() {
std::cout<<"constructor"<<std::endl;
}
InitTest::~InitTest() {
std::cout<<"destructor"<<std::endl;
}
}
This program:
StaticTest.cpp
#include <iostream>
#include <StaticTestLib/InitTest.h>
StaticTestLib::InitTest test;
int main() {
std::cout << "program main" << std::endl;
std::cout << "program end" << std::endl;
return 0;
}
… outputs:
constructor
static var init
code before constructor
program main
program end
destructor
But this program:
#include <iostream>
#include <StaticTestLib/InitTest.h>
int main() {
std::cout << "program main" << std::endl;
StaticTestLib::InitTest test;
std::cout << "program end" << std::endl;
return 0;
}
… outputs:
static var init
code before constructor
program main
contructor
program end
destructor
My guess is that this is related to the order of static objects initialisation in different compilation units being undefined.
The second code snippet where you create a test object in your main is easy to explain. Static initialisation will always happen before any code is executed, so by the time you enter main, your notifier_header object is definitely created.
Now, when you create your test before main, you have two static objects. notifier_header object does not depend on your InitTest: it is scoped within that class, but it is stored in static memory. You seem to reference the notifier_header in your InitTest.cpp, which is a different compilation unit to main. A compiler is free to do static allocations in any order for those two units, provided that there is no interdependencies.
If your constructor depended on notifier_header, you could use it as a singleton. Create a function that returns an instance of a static object (headerInstance in the example below), and upon its call, the object will be created:
#include <iostream>
namespace StaticTestLib {
class notifier_header{
public:
notifier_header(){
std::cout<<"static var init"<<std::endl;
}
};
class InitTest {
public:
InitTest();
virtual ~InitTest();
notifier_header& headerInstance();
};
}
Static library source file (InitTest.cpp)
#include "InitTest.h"
namespace StaticTestLib {
class notifier_cpp{
public:
notifier_cpp(){
std::cout<<"code before constructor"<<std::endl;
}
}_notifier_in_cpp;
InitTest::InitTest() {
headerInstance();
std::cout<<"constructor"<<std::endl;
}
InitTest::~InitTest() {
std::cout<<"destructor"<<std::endl;
}
notifier_header& InitTest::headerInstance() {
static notifier_header _header_notifier; // will only be constructed once
return _header_notifier;
}
}
The output I get:
static var init
constructor
code before constructor
program main
program end
destructor
Please take a look at this simple code:
// A.h
#pragma once
#include <iostream>
class A
{
public:
A();
~A();
int a;
private:
};
A::A() :a{3}
{
}
A::~A()
{
std::cout << 42 << std::endl;
}
In Main.cpp I have a global function:
// Main.cpp
#include "A.h"
A GlobalGetAByValue(){
static A a{};
return a;
}
int main(){
A a = GlobalGetAByValue();
int val;
std::cin >> val;
return 0;
}
And now interesting - if in close a console with close button I have an exception in A's destructor. If I enter some values and press enter - console closes without exception. If I initialize variable a as local variable or if I create a pointer with new keyword and delete it just before return everything works fine.
So I only get this cout error in destructor when I'm using static A. But why?
As it said in section 3.6.3 "Termination" of the C++03 standard:
"Destructors for initialized objects of static storage duration (declared at block scope or at namespace scope) are called as a result of returning from main and as a result of calling exit."
so, i can make a suggestion, that when destructor called, there no any valid ostream object (like cout in this case).