Providing pointer to private member from within class - c++

I realise that providing a method which returns a pointer to a private method breaks encapsulation, and exposes the field to anyone who uses the class. However, suppose the following:
You have a class which calls the method of another class (which expects a pointer to some private field), and the address of the private member is passed as a parameter to this method.
As far as I can see, as long as the private member's address is only exposed in a way controlled by the developer of the class, this doesn't break encapsulation (i.e. the developer knows exactly how it's going to be used). Of course, the method called could (assuming you didn't write it) expose the private member, but do we need to look that far ahead? I've seen this done countless times, so I guess it's not the result of bad design practises?
Is it bad practise to write method which take pointers to private members of other classes and modify them? Should each class only "look out for themselves"?

It would be a bad design because most classes have getters and setters to read and write to the object. So if that function needs to read and write then it should ask for object reference, not for pointer to any private memeber.
And in most of cases when function needs a reference for variable, it asks for reference to a constant value.

I realise that providing a method which returns a pointer to a private method breaks encapsulation, and exposes the field to anyone who uses the class.
This is not true to begin with.
A class that has a method that returns a pointer as part of its interface is absolutely fine, and the fact that it returns a member variable is an implementation detail that the outside world does not need to know.
Now, that being said, it is difficult to design a sane class interface that involves functions that return non-owning pointers, so it's something we tend to avoid.
Edit as far as the second part of the question goes:
Any class is supposed to sanely handle any possible permutation of usage of its public interface (including de-referencing any returned pointers). What or who uses the public interface is supposed to be entirely irrelevant, and you should assume that all users of the class will make use of the entire public API.
If you have parts of the class that you only want to make available to specific types or functions, then that's exactly what friend is for. But this has nothing to do with pointers to members, it applies to any and all parts of the class.

Related

Why do references see private members? [duplicate]

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.

inherited friendship

now before you guys start raging, here me out. Yes, i recognize that it is actually intended for friendship to not be inherited, i'm just trying to find some way to get something similar to it. Here is my situation (no real code, just theory). i'm working on a simple abstract game engine framework, and at first, i was just going to do the straightforward object oriented/ inheritance approach of breaking object types down. Now, it sounded really nice on paper, taking entities and breaking them into subcategories of physics, animated, and unmoving scenary and all it's subcategories. This however, became a hazardous, difficult to work with mess of entirely different objects and quite a bit of dangerous casting that could easily cause problems should i miss on something i needed to enforce instead of the compiler, which is always a good sign that there is a better solution.
So, I propose a different method of abstractly representing objects. I wish for there to be one entity class that all entities derive from which contain a vector, or some other dynamically growable array that works best, That will contain objects i'd call behaviors. The behaviors would be updated after a specified amount of time, which will affect the members of the object specified. Here are some examples.
class Force : behavior;
/*this would be a force, added to the behavior list and apply a constant
acceleration vector to the object until removed from the behavior list. (or
it's lifetime is exhausted) */
class attackThought : behavior;
/* For an ai, this would change how it reacts to a scenario by replacing or
even adding actions that it should perform given the change in position
or environment at update.*/
class animation : behavior;
/* You could create an animation, specify the animation that it is to perform,
add it to the behavior list, and during the time update, it will adjust the
vertex buffer accordingly, removing itself from the list when the animation
is done */
The problem is, i want to derive from a base behavior class, that implements some of it's virtual functions in different ways that will mostly change private members of the entity objects, (such as an objects vertex buffer). i don't want to have to manipulate too much of the basic entity code so that it can, (for the most part), be treated similarly to other objects, I only want their behaviors to be entirely manipulable/derivable. can anyone think of a way to make this system work in c++, cause i think it might be really cool :P.
btw, by way of friendship, i mean the base class behavior friending some derived entity class which can effect it's private members. For example, let's say i have a model class that derives from entity, and i want to friend a derived class of behavior called animation, and then later derive a class from model to a more specific type of object for some reason, how can an animation object manipulate the private members of this new model deriving object.
or can it? opinions on how viable this approach might be are also welcome, (as long as they actually contain critcism).
I have seen through the years that there are 2 different points of view on friendship and how it affects encapsulation:
It helps improve encapsulation by not making members public to everybody, and only making them accessible to a controlled subset of entities.
It reduces encapsulation for the obvious classic reasons that the object should be self contained and should be the only entity to modify its internal parts, etc.
I tend to avoid using friendship and try to work around it. I prefer to encapsulate everything, not just to make it private, but to be able to change how its implemented internally without affecting the users of the class. If you want a base class to be able to modify the attributes of a derived class, maybe you could consider using a Template Method design pattern. Whereby the base class orchestrates calling methods on the derived classes, and be sure to have generic, abstract manipulation methods defined in the base class.
As for making all the attributes of a class public "just in case", (sounds very dangerous) I think it would be better to start off making them all private, and consider making individual attributes public as the needs arise.

Why can I access private variables in the copy constructor?

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.

Should I create multiple classes?

This applies to several cases in my application:
I have 3 or 4 functions that belong together, one is a starting function that creates and frees the required memory structures and calls the other functions as appropriate. The other functions also call themselves repeatedly. Only the starting functions is called from outside, and only once or not at all per application-run.
Currently, I pass pointers to the memory structures from the starting function as function arguments, but the argument list is getting quite long in some cases.
Is there any argument against creating classes for all these cases and making the pointers to the memory structures members?
Definitely go for a class here. That's what objects and classes are designed for.
It seems to be a quite typical use case for classes: Just add the "memory structure" as protected member of the class and initiliaze it in the constructor.
The member functions (aka "method") than can work on the data.
If you have different, but similiar use cases, you may also make use of subclassing, so you create a base class with default implementation and create some derived class that overwrites some of the methods with an own implementation.
But note, that you could also use other members varibales to set the behaviour at runtime (e.g. a bool that is used to toggle on or off a specific behaviour).
Your question is too abstract to see what is the best solution for your case. Remember, often there are a lot of solutions - and so there is more than one good solution.
It sounds to me like these functions belong in a class - with the internal functions private or protected - likewise with the members.
Yes, relate them all within a class.
This will also give you a cleaner code which might help you minimize the functions' arguments lists.
In simple words an object can be anything you decide. Say a person. This is an object which I'll decide to define as a class if I'll write a program that needs to keep information regarding people.
There are much better explanations than this, just google/wikipedia it.

Accessors vs. public members

I have a class with a lot of built-in type members with read/write access. Should I make them public members and provide get/set methods for each one? How about structures?
The whole reason to have accessors (getters) and modifiers (setters) is to provide yourself with an extra level of indirection.
This extra level of indirection allows you to provide a read only view of your variable to a public interface, while not allowing your data member to be changed. You could still use a private or protected setter.
Setters allow you to do special error checking, validation and corrections when a value is set. For example setDirectory(const std::string &strPath), you could make sure there is a terminating slash if the user didn't specify one. This ensures that your class state will always be valid.
Getters can also shield your members from having them exposed to allow pointers to them. By not allowing pointers to them from the outside, you can ensure that if your object goes out of scope it won't lead to a crash.
The extra level of indirection for getters/setters also allow you to be able to change the data member that they encapsulate.
With a getter you can also obtain different views of your data, example: getMinutes, when your data member is actually stored in seconds.
This is not the reason to use them, but a nice side effect of using getters and setters is that you can set a breakpoint inside your modifier for example to see exactly when it is changed.
Whether you should use them or not is a judgement call based on your need. If you have so many members that it is a huge pain to provide getters and settings you could consider storing the data members in a struct and using that struct inside your class instead. You could even provide getters/setters for an object for the whole struct at once.
If there are invariants you need to preserve, then yes. Otherwise, don't bother.
Firstly, if your class has a lot of data mamebers it is probably not well designed. You may need to consider splitting it into multiple classes or storing the data in structures such as maps.
As regards providing accessors, the question is will you ever want to modify the access, possibly preventing it. If the answer is yes, then you need access functions. On the other hand, if your class is really just a bag of bits, with no behaviour, then make it a structure.
You should use public data members only
in structures, that you don't expose to client code (eg. bind-style functors) - it's useless to protect structures that noone outside will ever get
if their types encapsulate the logic of set/getting them (eg. if you create a class ObservableAttribute)
if they are const-members in an immutable structure (you can't do much except to read them if they're immutable)
If you create a public data member, you have to be sure that its value is fully orthogonal with other members of the class. Eg., you disable future possibilities of
observing changes to the member
making the member play any part in the class' invariant
disabling access to the member
changing the implementation of the member (eg. computed vs. cached vs. stored) if performance needs it
Using get/set methods for private/protected data members is a bad design.
It causes client code to be dependent on the implementation details of your class.
Changes in your class causes changes in client code.
However get/set methods for public members can be used. But it is always good to avoid them.