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.
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.
If we use constructors do we need to use setters and getters. I am totally confused between these terms could someone please elaborate.
If we use constructors do we need to use setters and getters
First of all you cannot have a class without a constructor, when you do not provide any compiler will generate them for you. You should not use setters and getters unrelated if you define your own constructor or not. When you design a class you design it's interface and then add member variables to implement that behavior and those members are internal representation of the class and outside world should not be aware of them - that is what data encapsulation is for and that's why we make them private or protected. When you add members first and then blindly provide getters and/or setters - that is a wrong approach to OOD.
Use constructors to create objects. Use getters to get information from an already existing object. Use setters to change an already existing object.
Any particular class may will need one or more of these things but not every class will need all of them. In particular immutable classes can't be modifed after they've been created so don't need setters.
The two things are very different.
A constructor is a function that is called by the system whenever an object is created. If you don't define one yourself, the compiler will provide a default one. Whatever happens, a constructor will be called exactly once for each object you create. Its purpose is usually to set up valid values for all members of the class.
By contrast, getters and setters are just regular functions — methods whose purpose is to provide access to individual members of a class (read and write acces, respectively). There is no requirement to provide one, and they are not automatically generated; conversely, if one is provided, it may be called as often as you like.
Hopefully it's clear how a constructor differs from set/getters.
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.
Suppose a class contains around 10 data members then what would be the proper way to initialize an object of that particular class? Create a constructor with 10 parameters or just provide a default constructor then use setter member functions or something else?
Basically I want to know how it is done in actual real life code?
thanks.
In actual real life code, I would be very reticent to have a class with 10 parameters that need to be set.
But also in real life, I know that this happens much more often than I would like. So here is what I would do:
First, evaluate your design. Do you really need all that stuff?
Second, if you really do need all that stuff, or if there's no way out due to a legacy design, then I would require every parameter in the constructor, and make the default constructor private. Everything should be initialized in an initialization list.
Sometimes when the data members and the class methods are sufficiently decoupled I would prefer to move all the data members to their own struct, and then have a member of that struct in the class. Take that struct by const reference and assign it in the init list. Make the struct member const.
Another [design] problem is that if you use class with that many arguments as a base class and then add more arguments (due to a requirement, for example), you may well forget to initialize them. So, yeah, refactor.
Isn't this really an OOP and design question?
What is the object here? Are all 10 fields attributes of that object? Can some be further grouped under another class?
Do you always have all 10 pieces of data when you need to instantiate the class? You can make constructors for the pieces you have and/or do setters/getters.
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.