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
Related
I have learned that I can never access a private variable, only with a get-function in the class. But then why can I access it in the copy constructor?
Example:
Field::Field(const Field& f)
{
pFirst = new T[f.capacity()];
pLast = pFirst + (f.pLast - f.pFirst);
pEnd = pFirst + (f.pEnd - f.pFirst);
std::copy(f.pFirst, f.pLast, pFirst);
}
My declaration:
private:
T *pFirst,*pLast,*pEnd;
The access modifiers work on class level, and not on object level.
That is, two objects of the same class can access each others private data.
Why:
Primarily due to efficiency. It would be a non-negligible runtime overhead to check if this == other each time you access other.x which you would have to if the access modifiers worked on object level.
It's also kind of semantically logical if you think of it in terms of scoping: "How big part of the code do I need to keep in mind when modifying a private variable?" – You need to keep the code of the whole class in mind, and this is orthogonal to which objects exist in runtime.
And it's incredibly convenient when writing copy constructors and assignment operators.
IMHO, existing answers do a poor job explaining the "Why" of this - focusing too much on reiterating what behaviour's valid. "access modifiers work on class level, and not on object level." - yes, but why?
The overarching concept here is that it's the programmer(s) designing, writing and maintaining a class who is(are) expected to understand the OO encapsulation desired and empowered to coordinate its implementation. So, if you're writing class X, you're encoding not just how an individual X x object can be used by code with access to it, but also how:
derived classes are able to interact with it (through optionally-pure virtual functions and/or protected access), and
distinct X objects cooperate to provide intended behaviours while honouring the post-conditions and invariants from your design.
It's not just the copy constructor either - a great many operations can involve two or more instances of your class: if you're comparing, adding/multiplying/dividing, copy-constructing, cloning, assigning etc. then it's often the case that you either simply must have access to private and/or protected data in the other object, or want it to allow a simpler, faster or generally better function implementation.
Specifically, these operations may want to take advantage of priviledged access to do things like:
(copy constructors) use a private member of the "rhs" (right hand side) object in an initialiser list, so that a member variable is itself copy-constructed instead of default-constructed (if even legal) then assigned too (again, if legal)
share resources - file handles, shared memory segments, shared_ptrs to reference data etc.
take ownership of things, e.g. auto_ptr<> "moves" ownership to the object under construction
copy private "cache", calibration, or state members needed to construct the new object in an optimally usable state without having to regenerate them from scratch
copy/access diagnostic/trace information kept in the object being copied that's not otherwise accessible through public APIs but might be used by some later exception object or logging (e.g. something about the time/circumstances when the "original" non-copy-constructed instance was constructed)
perform a more efficient copy of some data: e.g. objects may have e.g. an unordered_map member but publicly only expose begin() and end() iterators - with direct access to size() you could reserve capacity for faster copying; worse still if they only expose at() and insert() and otherwise throw....
copy references back to parent/coordination/management objects that might be unknown or write-only for the client code
You can access private members of a class from within the class, even those of another instance.
To understand the answer, I would like to remind you few concepts.
No matter how many objects you create, there is only one copy of one function in memory for that class. It means functions are created only once. However variables are separate for each instance of the class.
this pointer is passed to every function when called.
Now it's because of the this pointer, function is able to locate variables of that particular instance. no matter if it is private of public. it can be accessed inside that function. Now if we pass a pointer to another object of the same class. using this second pointer we will be able to access private members.
Hope this answers your question.
Copy constructor is class' member function and as such has access to class' data members, even those declared as 'private'.
why the man who made that compiler allow this behavior,
that we can see hidden members of an object (that its type is the same of the class where you access the hidden members) in copy constructor or in any method in the class.
The answer: because you when you are in the class that's mean you are the builder or the designer of the class also mean that you know all data members and methods in that class that's why he allow this behavior because you build this class you know every thing about it unlike the users of the class they haven't to know every thing about the class like you.
the idea of hiding data members or method that help the users of this class and not confused them with non important things.
That's it.
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.
Is there a way to design a class, that neither it nor its descendants can be allocated automatically (on stack), but only dynamically (in heap)?
I have a 3D scene represented by a scene tree, each object has a parent and a number of children. All scene objects are inherited from some base class SceneObject. I would like to make it impossible to allocate such objects on the stack.
The only way I know to achieve this for a class is to declare a protected constructor and provide a factory (see Is it possible to prevent stack allocation of an object and only allow it to be instantiated with 'new'?). This does indeed work as I want for the class, but not for its descendants. Authors of derived classes need to explicitly declare constructors as non-public and I have no way to control it, thus providing possibilities for an error.
Are there any possibilities to achieve what I want? Any compromises maybe?
Not really, no.
You may be able to screw around with explicitly overriding operator new, or to mix the answer you linked to with templates, but otherwise you're hosed.
I'm going to go off on a limb and guess that your full problem involves resource management; if that's the case, check out the rule of three; if your class has a user-defined destructor, copy constructor, or copy assignment (operator=(const Something&)), you probably need all three.
The only way I know to do this is how your linked answer says - declare the class's constructor as private so nobody but the class itself can create instances of it, and then provide a public static method that creates an instance of the class on the heap. Everyone who wants an instance must call the static method.
I read this question "C++ Abstract Class: constructor yes or no?" and the answers belonging to it.
But according to answers, I understand that we need the constructor to initialize it data members, however I can use its member functions like setter functions in my derived class to initialize the data members, so Why is it important to define a constructor?
The default constructor definition and the member initializations make the class self contained regarding proper setup conditions (valid state).
Usage of setter methods to manipulate the class instance is optional for class clients (including inheriting classes).
You may consider adding more constructor signatures, that the clients can use to inititialze the class members with a single call, and don't require these applying additional setter calls.
It depends on the particular use case, what's more convenient and semantically correct in the end.
Two reasons:
To ensure the objects are always within a valid state.
You need a copy constructor to ensure that data gets copied correctly (e.g., no blind copies of dynamically allocated resources).
Probably more.
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.