just for the sake of experimentation, I'm playing with the singleton pattern. I was wondering if it could be possible to extend the usual singleton class
class A
{
private:
static A* m_instance;
A();
public:
static A* GetInstance();
}
A::A(){ ...some code}
A* A::m_instance = NULL;
A* A::GetInstance()
{
if( m_instance == NULL ) m_instance = new A();
return m_instance;
}
to a "multiple singleton" class, something like
class B
{
private:
static vector<B*> m_instances;
B();
public:
static B* GetInstance( unsigned int n = 0);
static B* GetNewInstance();
}
B* B::GetInstance( int n)
{
if( n < m_instances.size() ) return m_instances.at(n);
//Create a new instance and append it to m_instances
B * temp = new B();
m_instances.push_back( temp );
return temp;
}
B* B::GetNewInstance()
{
B * temp = new B();
m_instances.push_back( temp );
return temp;
}
The main problem I find in this pattern is the implementation of the destructor, because each nstance contains the vector of the instances so, if I delete an instance, I delete also the vector containing all other instances.
Is it possible to make this work? Or is it just a wrong pattern, plain and simple?
I assume you know that Singleton are smells of a bad design. See What is so bad about singletons?
To answer your question, you're right about the drawbacks of a "multiple singleton". A better design would be instead a singleton where the variable is a vector<A*>, or vector<unique_ptr<A>> if you're using C++11 (assuming each A can't be copied and needs to be instantiated once. Otherwise use vector<A>)
because each nstance contains the vector of the instances so, if I delete an instance, I delete also the vector containing all other instances.
No the vector<B*> will exist once for all instances since you've declared it static.
Who should call delete of your instances when? Usually using your technique the destructors of the singleton instance(s) never will be called.
Related
Is this possible?
class A {
static A *instance = NULL;
public:
A () {
if (instance) {
this = instance;
} else {
instance = this;
}
}
}
Does it have leak memory?
Do I need to oveload new operator?
No. Overlooking your compiler errors, your class won't work.
#Galik has provided invaluable sources for how you'd actually want to construct a singleton. But let's look at yours.
class A {
static A *instance = NULL; // NULL isn't even a thing, but assuming you mean nullptr you can't assign a static like this
public:
A () {
if (instance) {
this = instance; // this can't be assigned
} else {
instance = this; // this is correct
}
}
};
Which would give you the following:
class A {
static A *instance;
public:
A () {
// if there's no instance, this is the one we'll use
if (!instance) {
instance = this;
}
}
};
A* A::instance = nullptr;
Which doesn't stop you from constructing more than one anyway.
Not possible. If the constructor is exposed and called, a new object of A is inevitably created. The most elegant and widely used implementations of C++ singleton classes use static methods to return the single static instance, while hiding (e.g. make private accessible) the constructor.
Here's an example:
class A {
private:
static A *instance_; // use nullptr since C++11
A() {}
public:
static A& instance() {
if (!instance_)
instance_ = new A();
return *instance_;
}
};
A* A::instance_ = nullptr;
You cannot assign a value for this
On my work I have met with one bug which can be described as follows.
There are two classes, class A and class B:
class A
{
public:
void print(){}
};
class B
{
A* a;
public:
void init(A* _a) {
a = _a;
}
void PrintWithA()
{
a->print();
}
};
A* a;
B* b;
b->init(a);
// some code .....
delete a; // line 1
a = NULL;
// some code .....
b->PrintWithA(); // line 2
Object "b" doesn't know nothing about state of object "a". In line 1 "a"object has been deleted but on line 2 we continue to use it. When there are a lot of code it is very easy to make such mistake.
My question is the following - which approch to use to avoid some mistakes? I guess I could use observer pattern - but I think it is unjustifiably expensive solution.
Thank's.
You should use a weak ptr (http://en.cppreference.com/w/cpp/memory/weak_ptr)
basically you can provide class B with a weak ptr of A.
whenever comes time to access A, you can try to lock the weak ptr to see if it's still valid.
#include <memory>
class A
{
public:
void print(){}
};
class B
{
std::weak_ptr<A> a;
public:
void init(std::weak_ptr<A> _a) {
a = _a;
}
void PrintWithA()
{
if (auto spt = a.lock()) {
spt->print();
}
}
};
int main()
{
std::shared_ptr<A> a = std::make_shared<A>();
std::unique_ptr<B> b = std::make_unique<B>();
b->init(a);
// some code .....
a = nullptr;
// some code .....
b->PrintWithA(); // line 2
return 0;
}
To guard against that, either B needs to take ownership of the lifetime of A when the object B is constructed, or you need to make A reference counted.
C++11 I think has the concept of a shared pointer which maintains the references and will prevent the object A from being deleted if someone has a reference. See std::shared_ptr
If you are not using C++11 there is boost::shared_ptr which does essentially the same thing. But you need the boost library which I personally prefer not to use, but it's up to you.
Use them like this:
typedef std::shared_ptr<A> A_ptr;
A_ptr a = new A();
class B
{
A_ptr a;
public:
void B(A_ptr _a) {
a = _a;
}
void PrintWithA()
{
a->print();
}
};
Otherwise you could put something together yourself. Something along the lines of:
class A
{
public:
A(){
ref_count = 1;
}
void print(){}
void grab() {
ref_count++;
}
void release() {
ref_count--;
if (ref_count <= 0)
~A();
}
private:
int ref_count;
~A(){
delete this;
}
};
Inside B you'd assign the pointer and call grab();
Rather than call delete (which wouldn't work because it's private) you'd call
a->release() on the pointer.
Now this is not particularly fantastic because you can't use this form:
A a;
So it's not ideal. But if you're using some compiler that doesn't have a shared_ptr and you don't mind the limitation you may use this or a form of it. In general, use shared_ptr.
First of all, the line that says A* a; should probably be A* a = new A;.
In c++ you need to encode this awareness explicitly, it's not done automatically.
One thing you can do is check if _a is NULL inside PrintWithA, but this won't work if you make sure that you always set your pointers to NULL after delete[]ing them (which you've done)
Is there any way in C++ to create class within a function, and then prevent it from destructing?
like
class someclass {
public:
int x;
someclass() { x = 0; };
}
someclass::x;
and then somewhere
someclass * somefunction()
{
someclass somecl ();
return &somecl;
}
So we call function 'somefunction' and get pointer to class for later using. I need it to exist as long as program runs/it destructed by other function. Is there any way to do it without storing it inside arrays or vectors?
I'm not sure if what you're looking for is a way to define an object once and only once, returning a pointer to the same object each time, or to create a factory function that returns the a newly constructed object each time. If it's the second, look at previous answers. If it's the first, check out static variables. As an example, you could write
someclass * somefunction()
{
static someclass somecl ();
return &somecl;
}
This ensures that somecl is only defined once, when the function is initially run and that it will be alive until your program exits. (For a more precise description of the order of cleanup for static variables, see here.)
Yes, you have to allocate the memory on the heap and then delete the memory when you are done.
someclass * somefunction()
{
return new someclass();
}
int main()
{
someclass * myclass = somefunction();
// do stuff with myclass
delete myclass;
return 0;
}
someclass * somefunction()
{
return new somecl ();
}
You were very close :)
You could create it on the heap rather than the stack:
someclass * somefunction()
{
return new someclass();
}
You may also want to consider returning it in a smart pointer, to explicitly transfer ownership and control its lifetime.
I'm not exactly sure what you are driving at, I can imagine two different use cases where you would want to make a class indestructible.
Case 1: Singleton
The idiomatic way to do this, is to use a static instance of the class that's declared within an accessor function:
class Foo {
public:
static Foo& globalFoo();
private:
Foo() {};
~Foo() {};
};
Foo& Foo::globalFoo() {
static Foo myFoo;
return myFoo;
}
int main() {
Foo& myFoo = Foo::globalFoo();
}
That way, it is impossible for other code to either construct or destruct any instance of Foo, it can only use the one instance that's provided by the globalFoo() function.
Case 2: Wrapped allocation/deallocation
If you just want to force allocation/deallocation to happen via certain static functions, you only need to make both the constructor and the destructor private (just as in the singleton case), and add static functions to the interface for allocation/deallocation:
class Foo {
public:
static Foo* makeFoo();
static void destroyFoo(Foo* aFoo);
private:
Foo() {};
~Foo() {};
};
Foo* Foo::makeFoo() {
return new Foo();
}
void Foo::destroyFoo(Foo* aFoo) {
delete aFoo;
}
int main() {
Foo* myFoo = Foo::makeFoo();
Foo::destroyFoo(myFoo);
}
I am a very new programmer and a super beginner so I don't know too much about c++. I had specifically a question regarding making deep copies of pointers. What I have is a class A full of POD's and a pointer to this class (A *P).
I have a second class B which contains some other POD's and a vector of pointers to Class A.
I want to fill this vector of deep copies of A *P because in a loop I will be dynamically allocating and deallocating it. The following does not work. I believe its my copy constructor and overloading of the = operator. This is something I am doing for fun and learning.
class A
{
public:
.....
.....
.....
};
class B
{
public:
B();
~B();
B(const B &Copier);
B& B::operator=(const B &Overloading);
vector<A*> My_Container;
A* Points_a_lot;
int counter;
};
B::B()
{
counter=0;
Points_a_lot=NULL;
}
B::~B()
{
for(size_t i=0; i<My_Container.size(); i++)
{
delete My_Container[i];
}
}
B::B(const B &Overloading)
{
My_Container[counter]=new A(*Overloading.Points_a_lot);
}
B& B::operator=(const B &Overloading)
{
if(!Overloading.My_Container.empty())
{
Overloading.My_Container[counter]=new B(*Overloading.Points_a_lot);
}
return *this;
}
int main()
{ A* p=NULL;
B Alphabet;
for(....)
{
p=new A;
//some stuff example p->Member_of_A=3; etc..
Alphabet.My_Container[Alphabet.counter]=p;
Alphabet.counter++;
delete p;
}
return 0;
}
Any help will be great. I thank you for your time. Assume needed libraries included.
Okay, it seems to me that you are very confused about what operator= should be doing. Take a look at this page on operator overloading. This should get you started down the right path for that function.
Second, unrelated to your question check out this question about why your fields (member-variables, what-have-you) should be private.
There are many errors in your code. The main one is that your assignment operator and copy constructor are not deep copying a vector of pointers to A at all, rather, you are trying to put a B* in a location of the vector. What your assignment operator should do is to delete the elements the vector points to, and fill it with deep copies of the elements the source object's vector points to, after checking for self assignment. Your copy constructor should be filled with deep copies of the elements of the source objects.
Second, you should provide a method that adds elements to your class' vector, and let it set the counter variable internally. Having to coordinate both the vector and the counter externally is error-prone and one of the advantages of OOP is to avoid that kind of error. But better still, remove the counter variable altogether. You don't need it. YOur main would then be simplified to this:
int main()
{
B Alphabet;
for(....)
{
A* p = new A;
//some stuff example p->Member_of_A=3; etc..
Alphabet.appendElement(p); // B takes ownership, no need to delete in main
}
}
and appendElement could be
class B
{
public:
void appendElement(A* element) { myContainer_.push_back(element); }
// other public methods
private:
std::vector<A*> myContainer_;
};
You could further improve all of this by storing some kind of single ownership smart pointer instead of raw pointers. That would mean you don't have to worry about making deletions yourself. But that is probably beyond the scope of this question.
Now, you should consider avoiding the pointers altogether. In this case, you have to provide no copy constructors, assignment operators or destructors. The compiler-synthesized ones will do just fine. Your class B reduces to
class B
{
public:
void appendElement(const A& element) { myContainer_.push_back(element); }
// other public methods
private:
std::vector<A> myContainer_;
};
I do not fully understand what your requirements are so I attempted to fix the code and do a deep copy of B as that is what it seems you are asking.
#include <vector>
using namespace std;
class A
{
public:
A() : m_someInt(0), m_someFloat(0.0f) {}
// Redundant but putting it here for you to see when it is called (put break-point)
A(const A& a_other)
{
m_someInt = a_other.m_someInt;
m_someFloat = a_other.m_someFloat;
}
int m_someInt;
float m_someFloat;
};
class B
{
public:
B();
~B();
B(const B &Copier);
B& B::operator=(const B &Overloading);
void Cleanup();
void AddA(const A* a);
private:
vector<A*> My_Container;
A* Points_a_lot;
};
B::B()
{
Points_a_lot=NULL;
}
B::~B()
{
Cleanup();
}
B::B(const B &Overloading)
{
// Deep copy B
operator=(Overloading);
}
B& B::operator=(const B &Overloading)
{
// Delete old A's
Cleanup();
// Not using iterators to keep it simple for a beginner
for (size_t i = 0; i < Overloading.My_Container.size(); ++i)
{
// We need new A's which will then copy from the A's in Overloading's container
A* newA = new A( *(Overloading.My_Container[i]) );
// Done with allocation and copy, push_back to our container
My_Container.push_back(newA);
}
return *this;
}
void B::Cleanup()
{
// Assuming B is not responsible for cleaning up Points_a_lot
Points_a_lot = NULL;
for (size_t i = 0; i < My_Container.size(); ++i)
{
delete My_Container[i];
}
// Automatically called when My_Container is destroyed, but here we
// are open to the possibiliy of Cleanup() being called by the client
My_Container.clear();
}
void B::AddA(const A* a)
{
// We are adding a new A. In your code, the incoming A is going to
// be destroyed, therefore, we need to allocate a new A and copy
// the incoming A
A* newA = new A(*a);
My_Container.push_back(newA);
}
int main()
{
A* p=NULL;
B Alphabet;
for(int i = 0; i < 10; ++i)
{
p = new A();
//some stuff example p->Member_of_A=3; etc..
Alphabet.AddA(p);
delete p;
}
// If you put a breakpoint here and step through your code, you will see
// `B` deep-copied
B NewAlphabet = Alphabet;
return 0;
}
A few notes:
Newing and deleteing A in the loop is a bad idea. I realize you are doing this just to learn, which is great, but you may want to keep this in mind. Instead of destroying A through p, allow B to take ownership of the new A
Step through the code by using a debugger to see how it works
Try to post code that is as close to your original as possible when asking "why doesn't this work/compile"
Looks like you should instead have your My_Container consist of unique_ptrs so that when you assign, that the vector takes over ownership of the A instance
for(....)
{
p=new A;
//some stuff example p->Member_of_A=3; etc..
Alphabet.My_Container[Alphabet.counter]=p;
Alphabet.counter++;
delete p;
}
so instead declare My_Container as
vector<std::unique_ptr<A*> > My_Container;
then the code will be
for(....)
{
p=new A;
//some stuff example p->Member_of_A=3; etc..
Alphabet.My_Container[Alphabet.counter]=p;
Alphabet.counter++;
}
then if you need to do a 'deep copy' create a member in A called clone() or something and return a unique_ptr to the instance, use that when you need to create a copy.
You may want to take a look at boost::ptr_vector. Its interface is very similar to that of a std::vector but it is tailored for pointers and thus:
owns the resources (so no memory leak)
allow polymorphic storage (derived classes)
is const-correct and copy-correct
In order for the copy to work, you'll have to provide a A* new_clone(A const*) implementation.
Is there a standard way of maintaining a weak pointer to a parent (which is created using a shared pointer) in a child object in C++?
Essentially, I need to implement something on the lines of the following:
Class B;
Class A
{
...
private:
B m_b;
};
Class B
{
....
public:
void SetParentPtr(const boost::shared_ptr<A>& a)
{
m_parentPtr = a;
}
private:
boost::weak_ptr<A> m_parentPtr;
};
In the above all instances of class B need to hold a weak pointer to their parent (i.e object of class A). Class A objects are instantiated using a shared_ptr. I can think of a solution that uses a null deleter. But is that a standard way of doing something like this?
What you are doing above is explicitly supported by weak_ptr and shared_ptr, what happens when you try it? To be more precise, do what you are doing, without the null deleter, and then you use the standard behaviour on the weak_ptr to convert it to a shared_ptr as needed:
boost::shared_ptr<X> it=myWeakPtr.lock();
if (it)
{
// if the conversion succeeded, then the parent instance is still alive
}
There is an implicit conversion to weak_ptr, so you can use
void SetParentPtr(boost::weak_ptr<A> a) { }
directly.
check also boost::shared_from_this so the parent can give a pointer to himself without storing a weak_ptr explicitly.
Otherwise, this seems like a normal way to have a back-pointer. Just check whether there is a real added value in using back-pointers.
I would try to do something like this:
class A
{
A(){};
public:
static boost::shared_ptr<A> Create()
{
boost::shared_ptr<A> newPtr(new A());
newPtr->m_self = newPtr;
return newPtr;
}
// ...
void CreateChild()
{
m_childPtr = B::Create(m_self);
}
private:
boost::shared_ptr<B> m_childPtr;
boost::weak_ptr<A> m_self;
};
class B
{
B(){};
public:
static boost::shared_ptr<B> Create(boost::shared_ptr<A> ptrA)
{
boost::shared_ptr<B> newPtr(new B());
newPtr->m_parentPtr = ptrA;
return newPtr;
}
boost::weak_ptr<A> m_parentPtr;
};