I have to create simple singleton object factory for some types of objects. The problem is that I can't find smart way to prevent user from creating object instances by constructors. I know that I can move constructors to private/protected section but how will the factory create new objects now when constructors are private/protected? Making factory a friend of every class isn't really smart as I need to predeclare factory in every header and write aditional "friend Factory;" in every class. How to do this correct?
In the class, add a static member as pointer to the same type of the class. This will be your singleton.
When initializing an instance, the constructor is ran.
If this is the first time, the static member is null (never initialized), run the constructor normally and set default values. In the end also set the static member to this. Now your singleton is initialized.
In subsequent constructor calls, the static pointer will not be null. Make a temporary pointer to the class type. Set this pointer to this, then set this to the static member and delete the pointer. This will delete the new instance and return the same static instance instead, everytime.
Related
This question already has answers here:
What is the use of making constructor private in a class?
(23 answers)
Closed 8 years ago.
What is the use of declaring constructors in private section in C++?
We can declare friend functions and constructors in private section but what is the use?
If you declare the constructor as private, nobody but the class itself can create a new instance of it. Most likely, there is a static method returning a class instance instead. This grants some control about the amount of instances that exist in a given program.
The singleton pattern is one application of this practice. By using a private constructor and some other tricks, you can make sure that only a single instance of this class exists, because the user cannot just create a new instance on his own.
There are many scenarios for having private constructors.
Eg:
Restricting object creation
For singleton patterns
Restricting certain type of constructor (e.g. copy constructor, default constructor)
Private constructor means a user can not directly instantiate a class. Instead, you can create objects, where you have static class functions that can create and return instances of a class.
Another use is to prevent inheritance of your class, since derived classes won't be able to access your class' constructor. Of course, in this situation you still need a function that creates instances of the class.
Also it is commonly used in the Singleton pattern where the object is accessed through a static member function, Otherwise everyone can create an instance of your class, so it's not a singleton any more. For a singleton by definition there can exist only one instance.
E.g. by making constructor private, you can control the constructions of objects. Maybe you want that only n instances of your object are existing at the same time. You can create a function that counts this. See also Singleton pattern
If each member function is only contained once per class (to be shared by all instances) what exactly is the purpose of declaring a member function static? Is it like a function being declared const, in that it modifies a particular type of data (in this case, static data members)?
Normal member functions require a class instance to run. Static methods can be called directly without first creating an instance of the class.
Normal method:
MyClass myClass;
myClass.NormalMethod();
Static method:
MyClass::StaticMethod();
So normal methods are perfect for functions that work with the class data. If a method doesn't need to work with the class data, then it would be a candidate for possibly being made static.
Class methods, static or otherwise, can access private members of any of that class's objects, not just its own instance. Same goes for static methods, which don't have an instance unless you pass one to them.
You could also use a free function and declare it a friend, but a free function implies a higher level of abstraction that may operate on objects of different classes. A static class method says "I only make sense in light of my class"
One application of static methods is to create instances and return pointers. For example, there may be derived classes that the caller isn't supposed to know about - the "factory" function knows which derived class to use.
Of course when you need to create an object, you probably don't already have an object to use for that, and even if you do that other object isn't relevant.
Basically, sometimes some action is an aspect of the abstraction that a class provides, but that action isn't associated with a specific object - or at least not one that already exists. In that case, you should implement the action as a static function.
Similarly, some data is related to the abstraction provided by a class but not to a particular instance of that class. That data is probably best implemented as static member variables.
I have an abstract class, CAbstract, and want to have a member of this type in another class, CClass. If I make it a pointer, I will have to take care of the deleting myself, and do would like to avoid this.
If I make it a reference, will it get deleted automatically when the CClass gets deleted?
Can I make it a shared_ptr? Can shared_ptr manage abstract classes and pointing to derived classes?
References don't automatically deallocate anything; shared_ptr does. As long as you follow the rules of C++, it should handle inheritance situations gracefully. More specifically, since shared_ptr's destructor calls delete by default when the reference count drops to zero, you need to implement the (virtual) destructor properly to make shared_ptr work.
So I have the standard C++ setup with an object that stores another object. The stored object is owned completely, it's never leaked to the outside. The member is non-const.
class Container
{
private:
Contained item;
}
As I understand, when my Container is instantiated the default constructor will be called on the item member and I don't have to manage it in the initializer list.
Also do I understand it correctly that when my object is destroyed the dtor on the item will be called automatically?
Another option would be to store it by reference of course
class Container
{
private:
Contained& item;
public:
Container() : Contained()
{
}
}
in which case I don't know whether I should delete it in the dtor.
Yet another option is to store it by ptr
class Container
{
private:
Contained* item;
public:
Container()
{
item = new Contained();
}
~Container()
{
delete item;
}
}
Knowing that my item never gets returned to the caller and never bleeds into the outside API and never gets reassigned, what is the best way to proceed? As I mentioned, the item member is not const
(it will be a self-resizing data structure).
The easiest is to store the object itself. Using reference for this purpose is, I would say, confusing. One advantage with using the pointer is that you then may be able to avoid defining the Contained type in the header file - you can instead forward declare Contained, and keep all the details inside the .cpp file.
The first way is the best way in my opinion (it appears you don't need the object to be lazily constructed). The second way requires that you pass in the object from the outside and that it's lifetime is guaranteed, and the third way is really only good if you want lazy instantiation (i.e. only create the object on first use).
In this case, it's best to store the object itself, yes. Storing it by reference will only create an alias to the object, so your class is not the actual owner. Storing via a pointer is useless, unless your object is a base class and you might want to store a derived object.
Contrary to Luchian Grigore, I’d go for pointer/reference method: storing the encapsulated object as a reference or pointers lets you forward-declare it, hence saving compilation time.
In addition to that, it lets you have init() and destroy() member functions that would in turn call the constructor and destructors of the encapsulated object, as well as perform initialization of the other parts of the object. This way, a bad initialization can be handled by the return value of init().
Most of the time, you want to reduce the dependencies on your class. If this class forms an integral part of the interface (even if the member is private) then you can assume that anyone using your class will be using this one.
In such a case, having it as a member variable makes sense.
Where it is an implementation detail of your class, you should hide this detail from the users by using a forward declaration, so use a type that allows a forward declaration.
It is highly unlikely that it will be a reference. A reference must be initialsed on construction of your class, and so the constructor would probably have to pass in the object it refers to. Declaring it with new and dereferencing is going to lead to confusion.
If it is a pointer, your class can manage its lifetime with the destructor. In this case I often will use a raw pointer as it is well under control and my destructor can happily delete it, assuming my class is non-copyable.
If you use shared_ptr, you can use a forward declaration. But beware that your semantics are now that if you copy your object, all the copies will have a pointer to the same underlying object. If this is not what you want, shared_ptr is probably wrong. In addition, if you use shared_ptr when your class is non-copyable, it isn't really shared.
So unless you can use unique_ptr which allows a forward declaration, I would go for the raw pointer and a non-copyable class.
If your member does remain an implementation detail but is something that is pretty standard, like a map or a vector, it is not worth "encapsulating it" to the extent of using a forward declaration, only the types that are contained within the map or the vector, but not the map or vector itself.
How is a class constructor define in IDL?
You don't. IDL is about interfaces, not how objects are constructed. Clients don't need to know those details, just how to interact with such an object when it's available on the network.
Constructor is used to create and initialize an object. However, a constructor creates the object locally, that is, within the address space of the process that calls the constructor. Because of this, a constructor cannot be used to create an object in a different process, and this is the reason why you cannot define a constructor for an IDL interface.
If you want to create an object in a different (server) process, you can use the factory pattern, which invokes an operation on an existing object in the server. E.g.,
interface ObjectFactory {
Object create(...);
...
};