singleton class with non-default constructor - c++

I've got a class that needs to become a singleton. All good and fine only that it has a non-default constructor, i.e. it takes three arguments.
The best I could come up with is, to set the constuctor private and then provide some kind of public "setup" function.
Are there any better solutions? My work around so far looks something like - any ideas to improve this are welcome!
#include <iostream>
class singltn {
private:
static singltn *instance;
int data;
// Private constructor so that no objects can be created.
singltn() {
data = 0;
}
int _AA;
int _BB;
int _CC;
public:
static singltn *getInstance() {
if (!instance)
instance = new singltn;
return instance;
}
void setup(int AA, int BB, int CC) {
_AA = AA;
_BB = BB;
_CC = CC;
}
int getData() {
return this->data;
}
void setData(int data) {
this -> data = data;
}
int getAA(){
return this->_AA;
}
};
//Initialize pointer to zero so that it can be initialized in first call to getInstance
singltn *singltn::instance = 0;
int main(){
singltn *a = a->getInstance();
a->setup(111,222,333);
std::cout << "dat " << a->getData() << " _AA " << a-> getAA() << std::endl;
a->setData(100);
std::cout << "dat " << a->getData() << " _AA " << a-> getAA() << std::endl;
singltn *b = b->getInstance();
std::cout << "dat " << b->getData() << " _AA " << a-> getAA() << std::endl;
return 0;
}

You can use a static factory/getter function that calls a private constructor. Something like this:
class Foo {
public:
static Foo& GetInstance() {
static Foo foo(param1, param2);
return foo;
}
private:
Foo(int a, int b) {
// ...
}
}
Of course, that requires your factory function to somehow know the parameters somehow.

Don't use real singleton (which handles creation + unique instance + global access), and adapt it:
class MyClass
{
private:
int data = 0;
int _AA;
int _BB;
int _CC;
static std::unique_ptr<MyClass> uniqueInstance;
MyClass(int AA, int BB, int CC) : _AA(AA), _BB(BB), _CC(CC) {}
MyClass(const MyClass&) = delete;
MyClass& operator =(const MyClass&) = delete;
public:
static void Create(int AA, int BB, int CC)
{
// if (uniqueInstance) throw std::runtime_error("Call it only once");
uniqueInstance = std::make_unique<MyClass>(AA, BB, CC);
}
static MyClass& GetInstance()
{
if (!uniqueInstance) throw std::runtime_error("Call Create before");
return *uniqueInstance;
}
int getData() const { return this->data; }
void setData(int data) { this->data = data; }
int getAA() const { return _AA; }
};
std::unique_ptr<MyClass> MyClass::uniqueInstance;
int main(){
MyClass::Create(111, 222, 333);
auto& a = MyClass::GetInstance();
std::cout << "dat " << a.getData() << " _AA " << a.getAA() << std::endl;
a.setData(100);
std::cout << "dat " << a.getData() << " _AA " << a.getAA() << std::endl;
}

Adapting Steve's Answer to provide a setup function for the singleton class:
class Foo {
public:
static Foo& GetInstance() { return SetupInstance(-1, -1); }
static Foo& SetupInstance(int a, int b) {
static Foo foo(a, b);
return foo;
}
private:
Foo(int a, int b) {
// ...
}
};
As the constructor of the static singleton get's only called once, multiple calls to SetupInstance will not re-create a new object of Foo, but always return the object which was created at the first call.

Related

A class with a pointer pointing to another class as a member variable and pushing it into vector

using namespace std;
class B {
public:
B() :m_i(0), m_Name("") {};
B(const int num, const string& name) :m_i(num), m_Name(name) {};
void showInfo() {
cout << this->m_i << ", " << this->m_Name << endl;
}
friend class A;
private:
int m_i;
string m_Name;
};
class A {
public:
A(const int num, const string& name) :m_i(num), m_Name(name), ptr(nullptr) {};
A(const A& orig) {
m_i = orig.m_i;
m_Name = orig.m_Name;
ptr = new B;
ptr = orig.ptr;
}
void showInfo() {
cout << this->m_i << " " << this->m_Name << endl;
if (ptr) {
cout << ptr->m_i << " " << ptr->m_Name << endl;
}
}
~A() {
delete ptr;
}
friend class C;
private:
int m_i;
string m_Name;
B* ptr;
};
class C {
public:
void function() {
A instanceA1(10, "Hello");
A instanceA2(11, "Hello");
A instanceA3(12, "Hello");
{//another scope
B* instanceB1 = new B(10, "Bye");
instanceA1.ptr = instanceB1;
B* instanceB2 = new B(11, "Bye");
instanceA2.ptr = instanceB2;
B* instanceB3 = new B(12, "Bye");
instanceA3.ptr = instanceB3;
}
DB.push_back(instanceA1);
DB.push_back(instanceA2);
DB.push_back(instanceA3);
DB[0].showInfo();
DB[1].showInfo();
DB[2].showInfo();
};
private:
vector<A> DB;
};
int main(void) {
C console;
console.function();
}
I had to build a copy constructor of A since there is a pointer as a member variable and as far as I know push_back() only does a 'shallow copy' of an object.
However, although my desired output is
10 Hello
10 Bye
11 Hello
11 Bye
12 Hello
12 Bye
it prints nothing.
And if I delete delete ptr; in A's destructor, it prints what I wanted but I'm pretty
sure there is a memory leak.
What did I do wrong here?
Here's your copy constructor:
A(const A& orig) {
m_i = orig.m_i;
m_Name = orig.m_Name;
ptr = new B;
ptr = orig.ptr;
}
You assign ptr to a new B but then you turn around and trash it so it points to the original B. I don't think that's what you want. How about this:
ptr = new B(*orig.ptr);
Does that help?

How to initialise static variables of class A in class B?

I tried using a static func in class A.
class A {
private:
static int a, b;
static void init(void) {
a = 1, b=0;
}
};
class B {
private:
A::init();
}
It is giving non-friend class cannot have a qualified name.
The following works:
class A {
private:
static int a;
public:
static void initialize();
void addStatic();
void getA();
};
class B {
public:
void initializeClassA();
};
int A::a = 10;
void A::addStatic() {
++a;
}
void A::getA() {
return a;
}
void A::initialize() {
a = 0;
}
void B::initializeClassA() {
A::initialize();
}
int main() {
A a;
B b;
std::cout << "Before Adding - " << a.getA() << std::endl;
for(int i = 0; i < 3; ++i)
{
a.addStatiic();
}
std::cout << "After Adding - " << a.getA() << std::endl;
b.initializeClassA();
std::cout << "After Reinitializing - " << a.getA() >> std::endl;
return 0;
}

why sizeof operator does not show size to be 20?

#include "iostream"
using namespace std;
class Algebra
{
private:
int a, b;
const int c;
const int d;
static int s;
public:
//default constructor
Algebra() : c(0), d(0)
{
s++;
a = b = 0;
cout << "Default Constructor" << endl;
}
//parameterized (overloaded) constructor
Algebra(int a, int b, int c1, int d1) : c(c1), d(d1)
{
s++;
setA(a);
setB(b);
cout << "Parameterized Constructor" << endl;
}
//copy (overloaded) constructor
Algebra(const Algebra &obj) : c(obj.c), d(obj.d)
{
s++;
this->a = obj.a;
this->b = obj.b;
cout << "Copy Constructor" << endl;
}
//Destructor
~Algebra()
{
s--;
cout << "Destructor Called" << endl;
}
//Setter for static member s
static void setS(int s)
{
Algebra::s = s;
}
//Getter for static member s
static int getS()
{
return s;
}
//Getter for constant data member c
int getC() const
{
return this->c;
}
//Setter for data member a
void setA(int a)
{
if(a < 0)
this->a = 0;
else
this->a = a;
}
//Setter for data member b
void setB(int b)
{
if(b < 0)
this->b = 0;
else
this->b = b;
}
};
int Algebra::s = 90;
int main()
{
Algebra obj1, obj2(1, 2, 3,4), obj3(obj1);
cout << "Size of object = " << sizeof(obj1) << endl;
return 0;
}
why the sizeof operator show size to be 16,where i have declared 5 data members of int type.it should add up all 5 data members and give the result as 20. i have also checked sizeof operator on static int variable separately which works fine.
The static member doesn't contribute to the size of a class instance, as you only need one copy for your entire program, not one per instance. Therefore, the size consists of 4 ints, which is 16 bytes on your platform.

C++ Destructor is not being called/Object is not being deleted - Potential Memory Leak [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
My first question is: I am having a lot of trouble figuring out why the Example class is being constructed greater than the others. Below is a short app using a Template counter to track how many times the constructor/destructor/copy constructor is called for each class. There are a total of three classes: Example, Deep, Child. Each has a copy constructor... ugh.
Also, my second question, is what would be the correct way to define the copy constructor for the Child class?
In the printStatus(), it displays:
COUNTERS::NEW_COUNTER = 60
COUNTERS::DELETE_COUNTER = 50
COUNTERS::CONSTRUCTOR_COUNTER = 90
COUNTERS::DESTRUCTOR_COUNTER = 80
Example count = 10
Deep count = 0
Child count = 0
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class COUNTERS
{
public:
static int NEW_COUNTER;
static int DELETE_COUNTER;
static int CONSTRUCTOR_COUNTER;
static int DESTRUCTOR_COUNTER;
};
int COUNTERS::NEW_COUNTER = 0;
int COUNTERS::DELETE_COUNTER = 0;
int COUNTERS::CONSTRUCTOR_COUNTER = 0;
int COUNTERS::DESTRUCTOR_COUNTER = 0;
/* template used for counting constructors/destructors to debug memory leaks */
template <typename T>
class Countable
{
static unsigned cs_count_;
public:
Countable() { ++cs_count_; }
Countable( Countable const& ) { ++cs_count_; }
virtual ~Countable() { --cs_count_;}
static unsigned count() { return cs_count_; }
};
template <typename T>
unsigned Countable<T>::cs_count_ = 0;
class Example : public Countable<Example>
{
public:
string a;
int b;
Example() {
COUNTERS::CONSTRUCTOR_COUNTER++;
a = "exampleString";
b = 5;
}
virtual ~Example() {
COUNTERS::DESTRUCTOR_COUNTER++;
}
// copy constructor
Example(const Example& e) {
COUNTERS::CONSTRUCTOR_COUNTER++;
this->a = e.a;
this->b = e.b;
}
};
class Deep : public Countable<Deep>
{
public:
int a;
string b;
Example* e;
Deep()
{
COUNTERS::CONSTRUCTOR_COUNTER++;
a = 3;
b = "deepString";
e = new Example();
COUNTERS::NEW_COUNTER++;
}
virtual ~Deep() {
if(e != NULL) {
delete e;
COUNTERS::DELETE_COUNTER++;
}
COUNTERS::DESTRUCTOR_COUNTER++;
}
// copy constructor
Deep(const Deep& x)
{
COUNTERS::CONSTRUCTOR_COUNTER++;
this->a = x.a;
this->b = x.b;
this->e = new Example();
COUNTERS::NEW_COUNTER++;
this->e->a = x.e->a;
this->e->b = x.e->b;
};
};
class Child : public Countable<Child>
{
public:
Deep d;
string name;
int age;
Example* e;
vector<Example> list;
vector<Deep> deep_list;
void init()
{
Deep* var = new Deep(); COUNTERS::NEW_COUNTER++;
deep_list.push_back(*var);
delete var; COUNTERS::DELETE_COUNTER++;
}
Child() {
COUNTERS::CONSTRUCTOR_COUNTER++;
name = "a";
age = 10;
d.a = 1;
d.b = "deep";
d.e = NULL;
e = new Example();
COUNTERS::NEW_COUNTER++;
list.push_back(*e);
init();
}
virtual ~Child() {
COUNTERS::DESTRUCTOR_COUNTER++;
if(e != NULL) {
delete e;
COUNTERS::DELETE_COUNTER++;
}
}
// copy constructor
Child(const Child& c)
{
}
};
void myChildFunction(){
Child* c = new Child();
COUNTERS::NEW_COUNTER++;
delete c;
COUNTERS::DELETE_COUNTER++;
}
void printStatus(){
cout << "COUNTERS::NEW_COUNTER = " << COUNTERS::NEW_COUNTER << endl;
cout << "COUNTERS::DELETE_COUNTER = " << COUNTERS::DELETE_COUNTER << endl;
cout << "COUNTERS::CONSTRUCTOR_COUNTER = " << COUNTERS::CONSTRUCTOR_COUNTER << endl;
cout << "COUNTERS::DESTRUCTOR_COUNTER = " << COUNTERS::DESTRUCTOR_COUNTER << endl;
cout << "Example count = " << Example::count() << endl;
cout << "Deep count = " << Deep::count() << endl;
cout << "Child count = " << Child::count() << endl;
}
int main()
{
for(unsigned int i=0 ; i < 10; i++)
myChildFunction();
printStatus();
return 0;
}
You are missing out on deleting some Example objects because of this line:
d.e = NULL;
in Child::Child().
You are allocating memory for e in the constructor of Deep. After executing the above line, that memory is leaked.
You can resolve that problem by:
Removing that line (or commenting it out),
Deleting d.e before making it NULL, or
Doing something else that prevents the memory leak.
Update, in response to comment
Copy constructor for Child:
Child(const Child& c) : d(c.d),
name(c.name),
age(c.age),
e(new Example(*c.e)),
list(c.list),
deep_list(c.deep_list)
{
COUNTERS::DESTRUCTOR_COUNTER++; // This is for Child
COUNTERS::NEW_COUNTER++; // This is for new Example
}
I removed all information that cluttered your code.
When using templates, constructors and copy constructors NEED the following: Example < eltType >(void);
in the class definition. All objects that inherit from Countables are known as derived classes. They also may call a derived class a child, and the class in which it is derived from is called the parent. I added the COPY_CONSTRUCTOR_COUNT to add clarification to the data which is being presented on the console/command prompt. Usually when trying to preform a task, large or small, doing it incrementally and by providing methods, for each task, saves you time and a headache. I removed the new_count and delete_count from the equation, because I felt that it was not needed.
You will notice that I added : Countable( * ((Countable < eltType > *)&e))
This is a requirement when designing a program that involves inheritance, which introduces the
topic of Polymorphism :D
What that bit of code does is that it gets a pointer of a Countable, which will point to the address of object e, which then allows access to all super classes of this class, but not including e's class.
NOTE: Since e is a derived class of Countable, this is valid statement.
For you second question, all of your data members are public, you can use an iterator to copy your data stored in you vectors.
As a concern from one programmer to another, I hope your code in practice is well documented, and all methods declared in your class are defined in a .cpp file.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class COUNTERS
{
public:
static int NEW_COUNTER;
static int DELETE_COUNTER;
static int CONSTRUCTOR_COUNTER;
static int DESTRUCTOR_COUNTER;
static int COPY_CONSTRUCTOR_COUNTER;
};
int COUNTERS::NEW_COUNTER = 0;
int COUNTERS::DELETE_COUNTER = 0;
int COUNTERS::CONSTRUCTOR_COUNTER = 0;
int COUNTERS::DESTRUCTOR_COUNTER = 0;
int COUNTERS::COPY_CONSTRUCTOR_COUNTER = 0;
/* template used for counting constructors/destructors to debug memory leaks */
template <typename T>
class Countable
{
public:
Countable<T>()
{
incrementObjectCount();
};
Countable<T>(Countable const&)
{
incrementObjectCount();
};
virtual ~Countable()
{
decrementObjectCount();
};
static unsigned count()
{
return cs_count_;
};
protected:
static unsigned cs_count_;
////////////////////////////////////ADDED////////////////////////////////////
protected:
void incrementObjectCount(void){ ++cs_count_; };
void decrementObjectCount(void){ --cs_count_; };
void incrementDeconstructorCounter(void){ ++COUNTERS::DESTRUCTOR_COUNTER; };
/////////////////////////////////////ADDED////////////////////////////////////
};
template <typename T>
unsigned Countable<T>::cs_count_ = 0;
class Example : public Countable<Example>
{
public:
Example() : Countable<Example>()
{
COUNTERS::CONSTRUCTOR_COUNTER++;
}
virtual ~Example()
{
incrementDeconstructorCounter();
}
// copy constructor
Example(const Example& e) : Countable<Example>(*((Countable<Example>*)&e))
{
// COUNTERS::CONSTRUCTOR_COUNTER++; This is copy constructor, you addmitted this from "Child" class CCstr
++COUNTERS::COPY_CONSTRUCTOR_COUNTER; // For even more information added this
}
};
class Deep : public Countable<Deep>
{
public:
Deep() : Countable<Deep>()
{
COUNTERS::CONSTRUCTOR_COUNTER++;
}
virtual ~Deep()
{
COUNTERS::DESTRUCTOR_COUNTER++;
}
// copy constructor
Deep(const Deep& x) : Countable<Deep>(*((Countable<Deep>*)&x))
{
//COUNTERS::CONSTRUCTOR_COUNTER++;
++COUNTERS::COPY_CONSTRUCTOR_COUNTER; // For even more information added this
};
};
class Child : public Countable<Child>
{
public:
vector<Example> list;
vector<Deep> deep_list;
void init()
{
deep_list.push_back(Deep());
list.push_back(Example());
}
Child() : Countable<Child>()
{
COUNTERS::CONSTRUCTOR_COUNTER++;
init();
}
virtual ~Child()
{
COUNTERS::DESTRUCTOR_COUNTER++;
}
// copy constructor
Child(const Child& c) : Countable<Child>(*((Countable<Child>*)&c))
{
++COUNTERS::COPY_CONSTRUCTOR_COUNTER; // For even more information added this
}
};
void myChildFunction(){
Child* c = new Child();
//COUNTERS::NEW_COUNTER++;not needed
delete c;
//COUNTERS::DELETE_COUNTER++; not need
}
void printStatus(){
cout << "COUNTERS::NEW_COUNTER = " << COUNTERS::NEW_COUNTER << endl;
cout << "COUNTERS::DELETE_COUNTER = " << COUNTERS::DELETE_COUNTER << endl;
cout << "COUNTERS::CONSTRUCTOR_COUNTER = " << COUNTERS::CONSTRUCTOR_COUNTER << endl;
cout << "COUNTERS::DESTRUCTOR_COUNTER = " << COUNTERS::DESTRUCTOR_COUNTER << endl;
cout << "COUNTERS::COPY_CONSTRUCTOR_COUNTER = " << COUNTERS::COPY_CONSTRUCTOR_COUNTER << endl;
cout << "Example count = " << Example::count() << endl;
cout << "Deep count = " << Deep::count() << endl;
cout << "Child count = " << Child::count() << endl;
}
int main()
{
for (unsigned int i = 0; i < 10; i++)
myChildFunction();
printStatus();
system("pause");
return 0;
}

in base class, how to define a container to contain function obj which can be any func of derived class?

I want to define a container in the base class, which contains function obj or anything that can make my purpose happen. These function obj can call derived classes' functions. they all take same parameters.
#include <vector>
#include <functional>
#include <iostream>
class Foo {
Foo() {}
virtual ~Foo(){}
virtual void init()
{ registerCallback(0, &Foo::print_ori ); }
void print_ori(int i) const { std::cout << i << '\n'; }
void registerCallback(int key, ??? cb ) // NOT SURE HOW TO DEFINE THIS
{
callbacks[key] = cb;
}
void runCallbacks(int key, int n)
{
auto i = callbacks.find(key);
if (i != callbacks.end()) {
(*i)(*this, n);
}
}
std::map<int, std::function<void(const Foo&, int) > > callbacks; // obviously, it's wrong. how to fix it?
};
struct Foo2 : public Foo {
Foo2(int num) : Foo(num) {}
virtual void init()
{
Foo::init();
registerCallback(11, &Foo2::print1 );
registerCallback(12, &Foo2::print2 );
}
void print1(int i) const { std::cout << " - Foo2.p1 - " << i << endl; }
void print2(int i) const { std::cout << " - Foo2.p2 - " << i << endl; }
};
int main()
{
Foo* obj = new Foo2();
obj->init();
obj->runCallbacks(12, 456);
}
Here's a way to achieve what your code looks like it's trying to do, without using function pointers:
class Foo {
Foo() {}
virtual ~Foo(){}
void print_ori(int i) const { std::cout << i << '\n'; }
virtual void do_runCallbacks(int v)
{
}
void runCallbacks()
{
print_ori(3)
do_runCallBacks(3);
}
};
struct Foo2 : public Foo {
Foo2(int num) : Foo(num) {}
void do_runcallbacks(int v)
{
print1(v);
print2(v);
}
void print1(int i) const { std::cout << " - Foo2.p1 - " << i << endl; }
void print2(int i) const { std::cout << " - Foo2.p2 - " << i << endl; }
};
int main()
{
Foo* obj = new Foo2();
obj->runCallbacks();
}
Now, there may well be reasons to do this completely differently, but I don't see why you should need both virtual functions and inheritance, AND function objects/function pointers. That seems quite wrong to me ("smells bad")
Edit:
Here's something I came up with, that solves the type of problem you describe after edits of the original question.
#include <iostream>
#include <map>
using namespace std;
class event_interface
{
public:
virtual void action(int n) = 0;
};
class event_manager
{
public:
event_manager(int n) : num(n) {}
void register_event(int key, event_interface *eh)
{
handlers[key] = eh;
}
void callback(int key)
{
auto h = handlers.find(key);
if (h != handlers.end())
{
h->second->action(num);
}
}
private:
map<int, event_interface *> handlers;
int num;
};
class handler1 : public event_interface
{
public:
void action(int n) { cout << "in handler1::action. n=" << n << endl; }
};
class handler2 : public event_interface
{
public:
handler2(int n) : data(n) {}
void action(int n)
{
cout << "in handler2::action. n=" << n
<< " data = " << data << endl;
}
private:
int data;
};
class multihandler
{
private:
class handler3: public event_interface
{
public:
void action(int n) { cout << "in handler3::action. n=" << n << endl; }
};
class handler4: public event_interface
{
public:
handler4(multihandler *m) : mh(m) {}
void action(int n)
{
cout << "in handler4::action. n=" << n
<< " data = " << mh->data << endl;
}
private:
multihandler* mh;
};
public:
multihandler(event_manager& em) : h4(this)
{
em.register_event(62, &h3);
em.register_event(63, &h4);
data = 42;
}
private:
handler3 h3;
handler4 h4;
int data;
};
int main()
{
event_manager mgr(3);
handler1 h1;
handler2 h2(77);
multihandler mh(mgr);
mgr.register_event(12, &h1);
mgr.register_event(13, &h2);
int evts[] = { 12, 63, 62, 13, 18 };
for(auto i : evts)
{
cout << "Event: " << i << endl;
mgr.callback(i);
}
}