Instance-level encapsulation with C++ - c++

I have a two-part question. First, I understand that C++ provides only class-level data encapsulation, meaning that all objects of the same class have access to one another's private members. I understand the reason for this, but have found some links (i.e. http://www.programmerinterview.com/index.php/c-cplusplus/whats-the-difference-between-a-class-variable-and-an-instance-variable/) which appear to contradict this point, suggesting that I could do the following:
class testclass {
private:
// Below would be an instance-level variable, and new memory for it is set aside
// in each object I create of class testclass
int x;
// Below would be a class-level variable, memory is set aside only once no matter
// how many objects of the same class
static int y;
}
What I would like to do is actually make this work, i.e., I would like to define a variable in a class which is private in each instantiation (this is my second question). Since the code snippet above does not appear to achieve this, is there a work around I can use to create data that is private to individual objects? Thank you!
EDIT:
It's true that I'm still learning OO basics. I'll use the ubiquitous car example to show what I'm trying to do, which I'm sure must be a common thing to try. I'd welcome any suggestions for how to rethink it:
class car {
private:
int mileage;
public:
car(int); // Constructor
void odometer();
};
car::car(int m) {
mileage = m;
}
void car::odometer() {
return mileage;
}
int main(void) {
car ford(10000), honda(20000);
cout<<ford.odometer(); //Returns 20000, since honda constructor overwrites private variable 'mileage'
}
Is there any way to get the odometer() method to return the mileage of either the ford or honda, depending on what I want?

Priviledge (public, private, protected) only applies to names. Only during the time when a name is resolved will the compiler apply permissions. Once compiled, all such information is gone.
In your example above, all uses of the names x and y within a scope that resolves to THOSE variables will be private to your class. Only functions declared in your class, be they static or not, will be able to access those variables by name.
All bets are off however if you give out the variable to other objects that can then refer to the variable by other names which have other permissions.
I'm not sure what you're asking with reference to "in each instantiation". AFAIK, there is no native way to make a variable private such that only that instance can access it. In all cases, instances can access each other's private parts.
There's some ways you could get around this I suppose. First is to templatize your class and give each instance a different type. You could do this with an integer template parameter or something. This could make life annoying though as you try to work with these types as the same kind of thing. You'd have to virtualize and have an abstract base class or something.
Currently that's the only method I can think of. All others depend on calling entities playing nice.
Generally speaking it's rare that you'd want to protect members from other instances. The usual case of the same type being passed to the same type is during copy and assignment, where you basically need all knowledge about the source to correctly copy. My bet is that you need to rethink what you're trying to do, whatever that is.

Related

Does operator overloading allows the access to private member without friend? [duplicate]

class Person
{
private BankAccount account;
Person(BankAccount account)
{
this.account = account;
}
public Person someMethod(Person person)
{
//Why accessing private field is possible?
BankAccount a = person.account;
}
}
Please forget about the design. I know that OOP specifies that private objects are private to the class. My question is, why was OOP designed such that private fields have class-level access and not object-level access?
I am also a bit curious with the answer.
The most satisfying answer that I find is from Artemix in another post here (I'm renaming the AClass with Person class):
Why have class-level access modifiers instead of object-level?
The private modifier enforces Encapsulation principle.
The idea is that 'outer world' should not make changes to Person internal processes because Person implementation may change over time (and you would have to change the whole outer world to fix the differences in implementation - which is nearly to impossible).
When instance of Person accesses internals of other Person instance - you can be sure that both instances always know the details of implementation of Person. If the logic of internal to Person processes is changed - all you have to do is change the code of Person.
EDIT:
Please vote Artemix' answer. I'm just copy-pasting it.
Good question. It seems that object level access modifier would enforce the Encapsulation principle even further.
But actually it's the other way around. Let's take an example. Suppose you want to deep copy an object in a constructor, if you cannot access the private members of that object. Then the only possible way is to add some public accessors to all of the private members. This will make your objects naked to all other parts of the system.
So encapsulation doesn't mean being closed to all of the rest of the world. It means being selective about whom you want to be open to.
See the Java Language Specification, Section 6.6.1. Determining Accessibility
It states
Otherwise, if the member or constructor is declared private, then
access is permitted if and only if it occurs within the body of the
top level class (ยง7.6) that encloses the declaration of the member or
constructor.
Click the link above for more details. So the answer is: Because James Gosling and the other authors of Java decided it to be that way.
This works because you are in the class Person - a class is allowed to poke inside it's own type of class. This really helps when you want to write a copy constructor, for example:
class A
{
private:
int x;
int y;
public:
A(int a, int b) x(a), y(b) {}
A(A a) { x = a.x; y = y.x; }
};
Or if we want to write operator+ and operator- for our big number class.
Just my 2 cents on the question of why the semantics of the private visibility in Java is class level rather than object level.
I would say that convenience seems to be the key here. In fact, a private visibility at object level would have forced to expose methods to other classes (e.g. in the same package) in the scenario illustrated by the OP.
In truth I was not able neither to concoct nor to find an example showing that the visibility at class-private level (like offered by Java) creates any issues if compared to visibility at object-private level.
That said, programming languages with a more fine-grained system of visibility policies can afford both object visibility at object level and class level.
For example Eiffel, offers selective export: you can export any class feature to any class of your choice, from {NONE} (object-private) to {ANY} (the equivalent of public, and also the default), to {PERSON} (class-private, see the OP's example), to specific groups of classes {PERSON, BANK}.
It's also interesting to remark that in Eiffel you don't need to make an attribute private and write a getter to prevent other classes from assigning to it. Public attributes in Eiffel are by default accessible in read-only mode, so you don't need a getter just to return their value.
Of course you still need a setter to set an attribute, but you can hide it by defining it as "assigner" for that attribute. This allows you, if you wish, to use the more convenient assignment operator instead of the setter invocation.
Because the private access modifier renders it visible only within the class. This method is still IN the class.
the private field is accessible in the class/object in which the field is declared. It is private to other classes/objects outside of the one it is located in.
First thing here we have to understand is all we have to do is must follow oops principles so encapsulation is say that wrap data within package(i.e. class) and than represent all data as Object and easy to access. so if we make field as non-private than
it's accessed indivisually. and it result into bad paratice.
With reflection concept in Java is possible modify fields and methods privates
Modificando metodos y campos privados con Refleccion en Java

How can I use a private member variable in a non-member function, when the variable happens to be a pointer?

Essentially my problem is that a function in a library I'm using, (function Foo in this code), requires a pointer to an object (Object* mbar) as a parameter. However, mbar is a private member variable to bar.
Normally, I'd just use a getter and pass by value, but if I pass the pointer, that would give direct access to the resource, which would break encapsulation. Any code could just call the getter and get free reign to modify it.
The next thing I thought was that I could use const pointers because they disallow modifying the resourse they point to, but as far as I could tell, I'd need to modify Foo to accept it, which is impossible as it's a library function.
The final thing I can think of is simply using a friend of Bar to call FoobarFunction, but I've always been told that friend functions are a last resort.
Is there a way to do this without breaking encapsulation in some way?
//Main.cpp
#include "Foobar.h"
int main()
{
Foobar fb;
Bar b;
fb.FoobarFunction(b);
return 0;
}
//Bar.h
#include "Object.h"
class Bar
{
private:
Object* mbar;
};
//Foobar.h
#include "Foo.h"
#include "Bar.h"
class Foobar
{
public:
void FoobarFunction(Bar bar)
{
Foo(bar.mbar);
}
};
The Easy Way Out
You can make the pointer const and then cast it when you pass it to the library function
Foo(const_cast<Object *>(bar.mbar));
This will work if Foo does not try to modify mbar. The cast removes the constness "in name only." Attempting to modify a secretly-const value can lead to Terrible Things.
But Really...
Even if there was a way to make Bar return a "read-only" pointer, the code sample in your question would still violate encapsulation. This particular flavor of non-encapsulation is called feature envy: the data lives in one object, but another object is doing most of the data manipulation. A more object-oriented approach would be to move the manipulation and the data into the same object.
Obviously, the sample code you've given us is much less complicated than your actual project, so I can't know the most sensible way to restructure your code. Here are a couple of suggestions:
Move the FoobarFunction into Bar:
class Bar
{
private:
Object* mbar;
public:
void FoobarFunction()
{
Foo(mbar);
}
};
Use dependency injection. Initialize mbar before creating Bar, then pass mbar into Bar's constructor.
int main()
{
Object *mbar;
Foobar fb;
Bar b(mbar);
fb.FoobarFunction(mbar);
return 0;
}
In this example, Bar is no longer the "owner" of mbar. The main method creates mbar directly and then passes it to whoever needs it.
At first glance, this example appears to break the guideline I mentioned earlier (the data and behavior are stored in different objects). However, there is a big difference between the above and creating a getter on Bar. If Bar has a getMBar() method, then anybody in the world can come along and grab mbar and use it for whatever evil purposes they wish. But in the above example, the owner of mbar (main) has complete control over when to give its data to another object/function.
Most object-oriented languages besides C++ don't have a "friend" construct. Based on my own experience, dependency injection is a better way of solving many of the problems that friends were designed to solve.
If the member is private, it's probably private for a reason...
If Bar has to be the only owner of Obj, then it should not expose it, as any other change to Obj might cause Bar to act incorrectly.
Although, if Bar does not have to be the only owner of Obj, you can either put a getter use dependency injection and pass it into Bar from outside, this way you can later pass it to foo as well.
A solution i think you should avoid is putting a call to foo inside Bar. This might violate the Single Responsibility Principle
I bealive that in this case tough, you can use a friend method.
I will refer you to a FAQ claiming that friend is not allways bad for encapsulation.
No! If they're used properly, they enhance encapsulation.
You often need to split a class in half when the two halves will have different numbers of instances or different lifetimes. In these cases, the two halves usually need direct access to each other (the two halves used to be in the same class, so you haven't increased the amount of code that needs direct access to a data structure; you've simply reshuffled the code into two classes instead of one). The safest way to implement this is to make the two halves friends of each other.
If you use friends like just described, you'll keep private things private. People who don't understand this often make naive efforts to avoid using friendship in situations like the above, and often they actually destroy encapsulation. They either use public data (grotesque!), or they make the data accessible between the halves via public get() and set() member functions. Having a public get() and set() member function for a private datum is OK only when the private datum "makes sense" from outside the class (from a user's perspective). In many cases, these get()/set() member functions are almost as bad as public data: they hide (only) the name of the private datum, but they don't hide the existence of the private datum.
Similarly, if you use friend functions as a syntactic variant of a class's public access functions, they don't violate encapsulation any more than a member function violates encapsulation. In other words, a class's friends don't violate the encapsulation barrier: along with the class's member functions, they are the encapsulation barrier.
(Many people think of a friend function as something outside the class. Instead, try thinking of a friend function as part of the class's public interface. A friend function in the class declaration doesn't violate encapsulation any more than a public member function violates encapsulation: both have exactly the same authority with respect to accessing the class's non-public parts.)

Should I use public or private variables?

I am doing a large project for the first time. I have lots of classes and some of them have public variables, some have private variables with setter and getter methods and same have both types.
I decided to rewrite this code to use primarily only one type. But I don't know which I should use (variables which are used only for methods in the same object are always private and are not subject of this question).
I know the theory what public and private means, but what is used in the real world and why?
private data members are generally considered good because they provide encapsulation.
Providing getters and setters for them breaks that encapsulation, but it's still better than public data members because there's only once access point to that data.
You'll notice this during debugging. If it's private, you know you can only modify the variable inside the class. If it's public, you'll have to search the whole code-base for where it might be modified.
As much as possible, ban getters/setters and make properties private. This follows the principle of information hiding - you shouldn't care about what properties a class has. It should be self-contained. Of course, in practice this isn't feasible, and if it is, a design that follows this will be more cluttered and harder to maintain than one that doesn't.
This is of course a rule of thumb - for example, I'd just use a struct (equivalent with a class with public access) for, say, a simple point class:
struct Point2D
{
double x;
double y;
};
Since you say that you know the theory, and other answers have dug into the meaning of public/private, getters and setters, I'd like to focus myself on the why of using accessors instead of creating public attributes (member data in C++).
Imagine that you have a class Truck in a logistic project:
class Truck {
public:
double capacity;
// lots of more things...
};
Provided you are northamerican, you'll probably use gallons in order to represent the capacity of your trucks. Imagine that your project is finished, it works perfectly, though many direct uses of Truck::capacity are done. Actually, your project becomes a success, so some european firm asks you to adapt your project to them; unfortunately, the project should use the metric system now, so litres instead of gallons should be employed for capacity.
Now, this could be a mess. Of course, one possibility would be to prepare a codebase only for North America, and a codebase only for Europe. But this means that bug fixes should be applied in two different code sources, and that is decided to be unfeasible.
The solution is to create a configuration possibility in your project. The user should be able to set gallons or litres, instead of that being a fixed, hardwired choice of gallons.
With the approach seen above, this will mean a lot of work, you will have to track down all uses of Truck::capacity, and decide what to do with them. This will probably mean to modify files along the whole codebase. Let's suppose, as an alternative, that you decided a more theoretic approach.
class Truck {
public:
double getCapacity() const
{ return capacity; }
// lots of more things...
private:
double capacity;
};
A possible, alternative change involves no modification to the interface of the class:
class Truck {
public:
double getCapacity() const
{ if ( Configuration::Measure == Gallons ) {
return capacity;
} else {
return ( capacity * 3.78 );
}
}
// lots of more things...
private:
double capacity;
};
(Please take int account that there are lots of ways for doing this, that one is only one possibility, and this is only an example)
You'll have to create the global utility class configuration (but you had to do it anyway), and add an include in truck.h for configuration.h, but these are all local changes, the remaining of your codebase stays unchanged, thus avoiding potential bugs.
Finally, you also state that you are working now in a big project, which I think it is the kind of field in which these reasons actually make more sense. Remember that the objective to keep in mind while working in large projects is to create maintainable code, i.e., code that you can correct and extend with new functionalities. You can forget about getters and setters in personal, small projects, though I'd try to make myself used to them.
Hope this helps.
There is no hard rule as to what should be private/public or protected.
It depends on the role of your class and what it offers.
All the methods and members that constitute the internal workings of
the class should be made private.
Everything that a class offers to the outside world should be public.
Members and methods that may have to be extended in a specialization of this class,
could be declared as protected.
From an OOP point of view getters/setters help with encapsulation and should therefore always be used. When you call a getter/setter the class can do whatever it wants behind the scenes and the internals of the class are not exposed to the outside.
On the other hand, from a C++ point of view, it can also be a disadvantage if the class does lots of unexpected things when you just want to get/set a value. People like to know if some access results in huge overhead or is simple and efficient. When you access a public variable you know exactly what you get, when you use a getter/setter you have no idea.
Especially if you only do a small project, spending your time writing getters/setters and adjusting them all accordingly when you decide to change your variable name/type/... produces lots of busywork for little gain. You'd better spend that time writing code that does something useful.
C++ code commonly doesn't use getters/setters when they don't provide real gain. If you design a 1,000,000-line project with lots of modules that have to be as independent as possible it might make sense, but for most normal-sized code you write day to day they are overkill.
There are some data types whose sole purpose is to hold well-specified data. These can typically be written as structs with public data members. Aside from that, a class should define an abstraction. Public variables or trivial setters and getters suggest that the design hasn't been thought through sufficiently, resulting in an agglomeration of weak abstractions that don't abstract much of anything. Instead of thinking about data, think about behavior: this class should do X, Y, and Z. From there, decide what internal data is needed to support the desired behavior. That's not easy at first, but keep reminding yourself that it's behavior that matters, not data.
Private member variables are preferred over public member variables, mainly for the reasons stated above (encapsulation, well-specified data, etc..). They also provide some data protection as well, since it guarantees that no outside entity can alter the member variable without going through the proper channel of a setter if need be.
Another benefit of getters and setters is that if you are using an IDE (like Eclipse or Netbeans), you can use the IDE's functionality to search for every place in the codebase where the function is called. They provide visibility as to where a piece of data in that particular class is being used or modified. Also, you can easily make the access to the member variables thread safe by having an internal mutex. The getter/setter functions would grab this mutex before accessing or modifying the variable.
I'm a proponent of abstraction to the point where it is still useful. Abstraction for the sake of abstraction usually results in a cluttered mess that is more complicated than its worth.
I've worked with complex rpgies and many games and i started to follow this rule of thumb.
Everything is public until a modification from outside can break something inside, then it should be encapsulated.(corner count in a triangle class for example)
I know info hiding principles etc but really don't follow that.
Public variables are usually discouraged, and the better form is to make all variables private and access them with getters and setters:
private int var;
public int getVar() {
return var;
}
public void setVar(int _var) {
var = _var;
}
Modern IDEs like Eclipse and others help you doing this by providing features like "Implement Getters and Setters" and "Encapsulate Field" (which replaces all direct acccesses of variables with the corresponding getter and setter calls).

What's the best way to access the internal data structure within a class?

I have a class A consisting of a bunch of internal data structures (e.g. m_data) and a few objects (e.g. ClassB):
class A
{
public:
...
private:
int m_data[255];
ClassB B[5];
}
What's the best way for B to access m_data? I don't want to pass m_data into B's function..
// updated:
Many thanks for the responses. Let me provide more contextual info.
I am working on an AI project, where I got some data (e.g. m_data[i]) at each time step. The class A needs to buffer these information (m_data) and uses a list of B's (example updated) to make inference. Class B itself is actually a base class, where different children derive from it for different purpose so I guess in this context, making B a subclass of A might not be clean (?)..
friend class ClassB;
Put this line anywhere in A's declaration if you want ClassB to access all of A's protected and private members.
One of:
Make ClassB a friend of A
Make A a sub-class of ClassB and make m_data protected rather than private
[In response to Mark B's comment]
If ever you feel the need to resort to a friend relationship, the design should be reconsidered - it may not be appropriate. Sub-classing may or may not make sense; you have to ask yourself "Is class A and kind of class ClassB?" If the question makes no sense intuitively, or the answer is just no, then it may be an inappropriate solution.
Ideally, you don't allow external access the data structure at all. You should rethink your approach, considering more the question "What are the functional requirements / use cases needed for ClassB to access instances of A" rather than offloading the management of the internal members to methods not managed within class A. You will find that restricting management of internal members to the class owning those members will yield cleaner code which is more easily debugged.
However, if for some reason this is not practical for your situation there are a couple possibilities that come to mind:
You can provide simple get/set accessor methods which, depending upon
your requirements, can be used to access either a copy of or a
reference to m_data. This has the disadvantage of allowing everybody
access, but does so only through well defined interfaces (which can
be monitored as needed).
ggPeti mentions use of friend, which may work for you, but it gives ClassB access to all of the internals of A.
A getData() function that returns m_data.
Use setData() to change the value.
So in the function in class B you would create a pointer to the class type A variable that you created. Lets just call this pointer 'p'.
Just do p->getData(), p.getData() may be the answer. I think they do the same thing but c++ uses the '->' and some other languages use the '.'. Don't quote me on that one though.
Good luck, sir. Hope I helped ya.
What's the best way for B to access m_data?
Depends on the use.
This is how would I do it :
class ClassB
{
// ...
void foo( A &a )
{
// use a's data
}
};
class A
{
//...
int m_data[255];
ClassB & B;
};
Depending on the implementation, maybe ClassB is not needed at all. Maybe it's methods can be converted to functions.

Declaration of struct variables in other class when obtained by getters

I am using Qt 4.5 so do C++. I have a class like this
class CClass1
{
private:
struct stModelDetails
{
QString name;
QString code;
..... // only variables and no functions over here
};
QList<stModelDetails> m_ModelDetailsList;
public:
QList<stModelDetails> getModelDetailsList();
...
};
In this I have functions that will populate the m_ModelDetailsList;
I have another class say CClassStructureUsage, where I will call the getModelDetailsList() function. Now my need is that I have to traverse the QList and obtain the name, code from each of the stModelDetails.
Now the problem is even the CClass1's header file is included it is not able to identify the type of stModelDetails in CClassStructureUsage. When I get the structure list by
QList<stModelDetails> ModelList = obj->getModelInformationList();
it says stModelDetails : undeclared identifier.
How I can able to fetch the values from the structure? Am I doing anything wrong over here?
Since struct stModelDetails is private, it is not visible from outside the class. You should declare it in the public section of your class instead:
class CClass1
{
private:
QList<stModelDetails> m_ModelDetailsList;
public:
struct stModelDetails
{
QString name;
QString code;
..... // only variables and no functions over here
};
QList<stModelDetails> getModelDetailsList();
...
};
You need to use the fully qualified name CClass1::stModelDetails. Now it will tell you it is private :)
You've already gotten a couple of suggestions for how to attack your problem directly. I, however, would recommend stepping back for a moment to consider what you're trying to accomplish here. First of all, you've said you only really want the name member of each stModelDetails item. Based on that, I'd start by changing the function to return only that:
QList<QString> GetModelDetailNames();
or, quite possibly:
QVector<QString> GetModelDetailNames();
The former has a couple of good points. First, it reduces the amount of data you need to copy. Second, it keeps client code from having to know more implementation details of CClass1. The latter retains those advantages, and adds a few of its own, primarily avoiding the overhead of a linked list in a situation where you haven't pointed to any reason you'd want to use a linked list (and such reasons are really fairly unusual).
The alternative to that is to figure out why outside code needs access to that much of CClass1's internal data, and whether it doesn't make sense for CClass1 to provide that service directly instead of outside code needing to access its data.
The problem is that you declared stModelDetails as a private class. Putting it in the public section should fix your problem.
There are two problems:
1. Already mentioned is that you need to move stModelDetails to the public section of your class.
2. Because it is nested, the proper name for it outside of the class is CClass1::stModelDetails.
If you really need access to it from the outside, you may want to consider whether it should be a member of CClass1 or if it should be a stand alone class or struct. I usually only use nested classes/structs when they are an implementation detail of my class.