How to automatically maintain a list of class instances? - c++

In my C++ project, I have an Engine class and an Object class.
My issue lies with how my instances of Object are created. Currently this is done through the use of a CreateObject(parameters) function in the Engine class. This adds a new instance of Object to an std::vector of Object instances.
I want to maintain this list of instances of Object in my Engine class, but without the need for the CreateObject(parameters) function. My reason for this is so that I can create new classes that can inherit from Object but still be added to this list. The reason for this list is so that (in Engine) I can iterate through every Object instance that has been created.
This would ultimately mean that I create my Object instances with something like Object newObject = Object(parameters);, but still have the Engine class maintain a list of all Object instances, without the need for Object to reference the instance of Engine or the list to add itself to this list (as in the instance of Object should not know about the list it is in). Can this be done?

You can define a static collection data member in your Engine class, update it in your Object constructor and destructor:
class Engine
{
friend class Object;
...
public:
static std::set< Object* > m_instances;
};
class Object
{
public:
Object();
virtual ~Object();
...
};
You increment it in constructors, and decrement it in destructors.
Object::Object()
{
Engine::m_instances.insert(this);
}
Object::~Object()
{
Engine::m_instances.erase(this);
}

I think your factory pattern approach is the good way to achieve this. The engine manages all the instances of Objects internally.
But if you want to make external instances, managed by the engine too, you must have to access a instance of the engine; even if that instance is a global variable, even if the Engine class implements a singleton pattern.
The second best approach to do that (The first is what yoa are doint yet, the factory), I think is to implement a singleton in the Engine:
class Object
{
Object
{
Engine::instance().addObject( this ); //Note that engine stores pointers. STL containers cannot store references.
}
~Object
{
Engine::instance().releaseObject( this );
}
};

Use a static
vector<Object*> Objects
variable in Engine class and static public function
Push(Object* obj) { Objects.push_back(obj); }
to push Objects to the list. Then in constructor of your Object class you would call
Engine::Push(this)

Like many have mentioned, factory architecture is a nice and clean way to go, otherwise you are going to have to have a global instance, static members or a singleton. However, a static approach would be to
make Object a friend of class engine and make the members static:
class Engine{
friend class Object;
private:
static std::vector <Object*> objectList;
};
This will allow Object to access private members of Engine statically. Then in the constructor of Object, add it to the list like so:
Object::Object(int randomparam1, const char* randomparam2)
{
Engine::objectList.push_back(this);
}

Related

what is the exact use and implementation of singleton class?

I know the singleton class does not allow to create more than one object. but as per my below code i can create as many objects as possible.
class Singleton
{
private :
static Singleton *m_Instance;
Singleton()
{
cout<<"In defailt constructor"<<endl;
}
Singleton(int x)
{
i = x;
cout<<"in param const"<<endl;
}
public:
static int i;
static Singleton* createInstance()
{
if(!m_Instance)
m_Instance = new Singleton(20);
Singleton sing;
return m_Instance;
}
};
int Singleton::i=0;
Singleton* Singleton::m_Instance = NULL;
int main()
{
Singleton *pt = Singleton::createInstance();
return 1;
}
Here I am able to create an object in the static function (as i can access constructor within the class) then where is the concept of Single object?
This isn't a singleton for the simple reason that you deliberately wrote something that isn't a singleton.
The idea is that you write the instance function so that it will only create one instance, and write other members so that they don't create any. Then, since they're the only functions that could create any instances, there will only be one.
If you remove the dodgy Singleton sing;, then you'll have a singleton implementation - only one instance will be created, the first time someone calls the function.
As with all attempts to implement this anti-pattern in C++, there are problems: the object is never destroyed, and the initialisation isn't thread-safe. There are various other approaches, each with their own drawbacks. I suggest you avoid global variables altogether, whether or not you dress them up as singletons or other anti-patterns.
The concept of single object comes when in your code, every time you need an instance of your Object, instead of using:
Singleton *myOwnSingleton= new Singleton(20);
You should always use:
Singleton *pt = Singleton::createInstance();
As the constructor is inaccesible outside of the class, the only way to create a Singleton is by Singleton::createInstance(), and if you read the code, only the first time that we call Singleton::createInstance() a new instance is created.
All subsequent calls to this method will return the already created object. So in all your execution you will only have one instance created.
But of course... you should delete the line
Singleton sing;
because it is a wrong utilization of Singleton. If you create a class called CAR but without wheels... it is not a car. And you make a class called singleton, but... with two objects of the same type. It's not beauty!

Use of public destructor when the constructor is private

I have seen code where the constructor has been declared as private while the destructor is public. What is the use of such a declaration? Is the destructor required to be public so that during inheritance the calls can be possible or is it a bug in the code?
The question might seem to be a bit short on information, but what I really want to know is if having a public destructor when the constructor is required to be private abides by the C++ rules?
Short Answer
Creating a constructor as private but the destructor as public has many practical uses.
You can use this paradigm to:
Enforcing reference counting (See Hitesh Vaghani's example).
Implement the singleton pattern
Implement the factory pattern.
Long Answer
Above I hinted that you can use private constructors and destructors to implement several design patterns. Well, here's how...
Reference Counting
Using private destructor within an object lends itself to a reference counting system. This lets the developer have stronger control of an objects lifetime.
class MyReferenceObject
{
public:
static MyReferenceObject* Create()
{
return new MyReferenceObject();
}
void retain()
{
m_ref_count++;
}
void release()
{
m_ref_count--;
if (m_ref_count <= 0)
{
// Perform any resource/sub object cleanup.
// Delete myself.
delete this; // Dangerous example but demonstrates the principle.
}
}
private:
int m_ref_count;
MyReferenceObject()
{
m_ref_count = 1;
}
~MyReferenceObject() { }
}
int main()
{
new MyReferenceObject(); // Illegal.
MyReferenceObject object; // Illegal, cannot be made on stack as destructor is private.
MyReferenceObject* object = MyReferenceObject::Create(); // Creates a new instance of 'MyReferenceObject' with reference count.
object->retain(); // Reference count of 2.
object->release(); // Reference count of 1.
object->release(); // Reference count of 0, object deletes itself from the heap.
}
This demonstrates how an object can manage itself and prevent developers from corrupting the memory system. Note that this is a dangerous example as MyReferenceObject deletes itself, see here for a list of things to consider when doing this.
Singleton
A major advantage to private constructors and destructors within a singleton class is that enforces the user to use it in only the manner that the code was design. A rogue singleton object can't be created (because it's enforced at compile time) and the user can't delete the singleton instance (again, enforced at compile time).
For example:
class MySingleton
{
public:
MySingleton* Instance()
{
static MySingleton* instance = NULL;
if (!instance)
{
instance = new MySingleton();
}
return instance;
}
private:
MySingleton() { }
~MySingleton() { }
}
int main()
{
new MySingleton(); // Illegal
delete MySingleton::Instance(); // Illegal.
}
See how it is almost impossible for the code to be misused. The proper use of the MySingleton is enforce at compile time, thus ensuring that developers must use MySingleton as intended.
Factory
Using private constructors within the factory design pattern is an important mechanism to enforce the use of only the factory to create objects.
For example:
class MyFactoryObject
{
public:
protected:
friend class MyFactory; // Allows the object factory to create instances of MyFactoryObject
MyFactoryObject() {} // Can only be created by itself or a friend class (MyFactory).
}
class MyFactory
{
public:
static MyFactoryObject* MakeObject()
{
// You can perform any MyFactoryObject specific initialisation here and it will carry through to wherever the factory method is invoked.
return new MyFactoryObject();
}
}
int main()
{
new MyFactoryObject(); // Illegal.
MyFactory::MakeObject(); // Legal, enforces the developer to make MyFactoryObject only through MyFactory.
}
This is powerful as it hides the creation of MyFactoryObject from the developer. You can use the factory method to perform any initilisation for MyFactoryObject (eg: setting a GUID, registering into a DB) and anywhere the factory method is used, that initilisation code will also take place.
Summary
This is just a few examples of how you can use private constructors and destructors to enforce the correct use of your API. If you want to get tricky, you can combine all these design patterns as well ;)
First thing: the destructor can be private.
having a public destructor when the constructor is required to be
private abides by the C++ rules?
It's totally working in C++. In fact, a great example of this scenario is the singleton pattern, where the constructor is private and the destructor is public.
In reverse order.
Is the destructor required to be public so that during inheritance the calls can be possible or is it a bug in the code?
Actually, for inheritance to work the destructor should be at least protected. If you inherit from a class with a private destructor, then no destructor can be generated for the derived class, which actually prevents instantiation (you can still use static methods and attributes).
What is the use of such declaration?
Note that even though the constructor is private, without further indication the class has a (default generated) public copy constructor and copy assignment operator. This pattern occurs frequently with:
the named constructor idiom
a factory
Example of named constructor idiom:
class Angle {
public:
static Angle FromDegrees(double d);
static Angle FromRadian(double d);
private:
Angle(double x): _value(x) {}
double _value;
};
Because it is ambiguous whether x should be precised in degrees or radians (or whatever), the constructor is made private and named method are provided. This way, usage makes units obvious:
Angle a = Angle::FromDegrees(360);
You make constructor private if you want to prevent creating more then one instance of your class. That way you control the creation of intances not their destruction. Thus, the destructor may be public.
One example in my head, let's say you want to limit the class instance number to be 0 or 1.
For example, for some singleton class, you want the application can temprary destroy the object to rducue memory usage. to implement this constructor will be private, but destructor will be public. see following code snippet.
class SingletoneBigMemoryConsumer
{
private:
SingletoneBigMemoryConsumer()
{
// Allocate a lot of resource here.
}
public:
static SingletoneBigMemoryConsumer* getInstance()
{
if (instance != NULL)
return instance;
else
return new SingletoneBigMemoryConsumer();
}
~SingletoneBigMemoryConsumer()
{
// release the allocated resource.
instance = NULL;
}
private:
// data memeber.
static SingletoneBigMemoryConsumer* instance;
}
//Usage.
SingletoneBigMemoryConsumer* obj = SingletoneBigMemoryConsumer::getInstance();
// You cannot create more SingletoneBigMemoryConsumer here.
// After 1 seconds usage, delete it to reduce memory usage.
delete obj;
// You can create an new one when needed later
The owner of an object needs access to the destructor to destroy it. If the constuctors are private, there must be some accessible function to create an object. If that function transferes the ownership of the constructed object to the caller ( for example return a pointer to a object on the free store ) the caller must have the right to access the destructor when he decides to delete the object.

Auto detaching objects?

I have a mother class that stores the pointers to some objects in a list. I want these objects to detach themselves from the list when they are destroyed.
Can anyone suggest some good ways to do this please?
The crude way is to store the container reference (or pointer) in the objects in the list and remove themselves in their destructors:
class Contained;
class Container {
std::list<Contained*> children;
public:
...
void goodbye(Contained*);
};
class Contained {
Container& c; // you set this in the constructor
public:
~Contained() { c.goodbye(this); }
};
Note that this makes the Contained class non-copyable.
The easy way is to use some framework that already provides such functionality. Eg. if you use Qt, you would just derive the Contained class from QObject and store QPointer<Contained> in the Container. The QPointer would be set to zero once the contained object is deleted.
Or, if you use some memory management facilities like boost::shared_pointer, (I assume the Container doesn't own the Contained objects, otherwise, it knows best when the child object dies), you would use a weak pointer in the Container, which has similar functionality.
you can add reference/pointer to the mother class in those classes and when destructor is called they call mother.Detach(this)

Inheritance - initialization problem

I have a c++ class derived from a base class in a framework.
The derived class doesn't have any data members because I need it to be freely convertible into a base class and back - the framework is responsible for loading and saving the objects and I can't change it. My derived class just has functions for accessing the data.
But there are a couple of places where I need to store some temporary local variables to speed up access to data in the base class.
mydata* MyClass::getData() {
if ( !m_mydata ) { // set to NULL in the constructor
m_mydata = some_long_and complex_operation_to_get_the_data_in_the_base()
}
return m_mydata;
}
The problem is if I just access the object by casting the base class pointer returned from the framework to MyClass* the ctor for MyClass is never called and m_mydata is junk.
Is there a way of only initializing the m_mydata pointer once?
It doesn't have members and you must maintain bit-for-bit memory layout compatibility… except it does and C++ doesn't have a concept of freely-convertible.
If the existing framework allocates the base objects, you really can't derive from it. In that case, I can think of two options:
Define your own class Cached which links to Base by reference. Make the reference public and/or duplicate Base's interface without inheritance.
Use a hash table, unordered_map< Base *, mydata > mydata_cache;. This seems most appropriate to me. Use free functions to look up cache data before delegating to the Base *.
You could initialize your private variables in a separate initialization member function, so something like this:
class MyClass {
public:
init() {
if (!m_mydata) {
m_mydata = f();
}
}
};
framework_class_t *fclass = framework.classfactory.makeclass();
MyClass *myclass = (MyClass*)fclass;
myclass->init();
char *mydata = myclass->getData();
It's hard to say if this is a good idea or not without knowing what framework you're using, or seeing your code. This is just the first thing that came to mind after reading your description.
You could create a wrapper for the factory of the framework. The wrapper would have the same interface, delegate calls to the framework but it could initialize the created base class instance before returning it. Of course, this requires you to change your code to use the wrapper everywhere, but if it is possible, after that you can be sure that the initialization happens properly.
A variation on this: use RAiI by wrapping the base class instances into a custom autopointer which could do the initialization in its constructor. Again, if you manage to change the code everywhere to use the new wrapper type instead of the derived class directly, you are safe.

Passing another class amongst instances

I was wondering what is the best practice re. passing (another class) amongst two instances of the same class (lets call this 'Primary'). So, essentially in the constructor for the first, i can initialize the outside instance (lets call this 'Shared') - and then set it to a particular value whilst im processing this class in main().
So 'Shared', may be an int, say 999 by now.
Now what if i create another instance of the main class 'Primary'? whats the best way to access the already initialized outside instance of 'Shared' - because if i don't handle this correctly, the constructor for 'Primary', when called again will just go ahead and create one more instance of 'Shared', and thus i loose the value 999.. i can think of some messy solutions involving dynamic pointers and if statements (just) but i have a feeling there might be a simpler, cleaner solution?
As I understand it:
You have a class A
You have a class B
For all members of class A there is a single instance of class B
You did not mention if any parameters from the A constructor are used to initialize B!
What happens to the parameters of the second A that are used for B?
So we will assume that B is default constructed.
We will also assume that you need the instance of B to be lazily evaluated otherwise you would just use a static member.
class A
{
B& bRef;
public:
A()
:bRef(getLazyB()) // Get a reference to the only B for your object.
{}
private:
static B& getLazyB()
{
static B instance; // Created on first use
return instance; // returned to all users.
}
};
Make the constructor take a pointer or reference to the shared class. It is easier to construct outside.
class Shared;
class Same
{
shared& shared_;
Same( Shared& s ) { shared_ = s; }
}
With appropiate use of const and other constructors etc.
This depends on the semantics of your classes. If the outside class is not really outside but some obscure implementation detail that happens to be shared between instances, pass the first instance to the constructor of the second instance and get a reference to the outside instance there.
If the outside class is really an outside class with a meaning by itself, create it outside and pass it to the constructor just as Mark suggested.
If not only two specific instances but all instances share the same instance of the outside class, think about making it a static member of the class, as Martin York suggested.