Protected get-functions for protected datamembers? - c++

We have two classes(A and B). Class A can only be created by classes who inherit from it(class A)
and class B can be created by a user.
Class A, version 1 has a private data member and has methods to aces the data in class A.
Class A, version 2 has a protected data member and therefore, no methods are needed for classes that will inherit from the class to aces the data in class A
Class A, version 1
class A
{
protected:
A() = default;
void set_data( T d );
T& get_data();
private:
T data;
}
Class A, version 2
class A
{
protected:
A() = default;
T data;
}
Class B
class B : public A {}
Which version of class A is the preferred one?

This is fairly subjective, but I would say 95% of the time neither one. Protected data makes your code just as hard to maintain as public so we rule that version out right away. But then also you almost never need a direct mutator (set) function, so we'll chop that function and then change the signature of the get function to const T& get_data() const;. Then we'll add a real interface to the parent to manipulate its state rather than having something external decide what the new state should be.

Your version one is always preferred. Data members of class should by default be private. Making data members all public is justified only in one case i.e If you just want to bundle-o-data. Only then you would use struct and make all data public. ( Like to capture the essence of what is s single node in linked list)
However, there is no such exception in case of protected. You can always make them private and provide accessors/mutators to those data members.
Downside of public data members is that they breaks the encapsulation. And it's difficult to maintain invariants as data is open to modification from all sides. Case of protected data member is bit restrictive than public in that it opens up ways for modification only through derived class members and friends. But still it's breaking encapsulation.
Conclusion :- All data members of class should always be private except in case it's intended to be used as bundle-o-data.
Along with that you would never want to pass handle to your internals to outside users as you have done in:-
T& get_data();
So, better way would be
const T& get_data();
except in some specific scenarios.

If you follow the common guidelines, data members should be private. Therefore, version 1 is preferred. On the other hand, completely trivial get/set pairs are a minor code smell in my opinion, so you may want to investigate why that member needs to be fully exposed to the derived class in the first place.

Use accessor functions if you need anything other than simple access to the variable: validating the value, maintaining class invariants, signalling changes, logging, etc. Note that get should return either a value or a const reference; your version, returning a non-const reference, can be used to assign arbitrary values to the variable, bypassing the set function.
If you only need simple access then some would suggest exposing the variable for the sake of simplicity; others would suggest using accessor functions for the sake of consistency (with other types that do need such things), or backwards compatibility (if you later decide you need functions after all). There's no compelling reason to prefer either option.

Related

Friend Class In C++

here im not understanding the concept very well or i am right.... So lets take this "friend" class example here:
class MyClass{
friend class AnotherClass;
private:
int secret;
}
class AnotherClass{
public:
void getSecret(MyClass mc){
return mc.secret;
}
}
So Yes... in the above code it will actually work if you do it... but in general, why cant you use getters and setters all the time instead of friend class? Is the reason of friend class usage because of "tediousness"?
friend is for when you don't want to expose getters/setters/internals to everyone, but just to a single class. So it's a tool for encapsulation.
For example, if you provided a public getSecret in MyClass, everyone could have access to that private variable even if they shouldn't know about it. This breaks encapsulation. friend is there to fix this problem, so that only those classes that need to know about secret have access to it.
As #nicomp said, "it's like giving your physical friend a key to your house but you don't know what they will do with it". So a friend class has unlimited access to all internals of the class it's friends with. This in unfortunate, but the key (no pun intended) here is to keep classes as small as possible so that this doesn't become a problem, which also would be according to the Single Responsibility Principle.
A public getter or setter permits anybody access. They have some uses, notably for maintaining class invariants when some property is changed, but a getter / setter pair that look like the following code are no better than public member variables for constraining access:
class A {
public:
int getX() const { return x; };
void setX(int x_) { x = x_; };
private:
int x;
};
The getX() and setX() functions do nothing but provide access to x. Everybody can use them, so anybody can change the value of x. There's no point making it private, then.
If, instead, only some classes or functions need to be able to change x, you can make them friends of class A. This restricts the access to only those friends, rather than giving it to everybody.
As such, friend is a tool for encapsulation, permitting the encapsulation to be wider than "just my own class" (private members) or "just my class and classes that derive from it" (protected members). A friend need not be in the same class hierarchy (it need not be a class at all; functions can be friends), but it still permits you to restrict access to only those things that actually need it.
Note that, like getters and setters, it should be used sparingly. Encapsulation is a good thing, and where possible the private members of your class should remain just that – private. friend is a tool that allows you to selectively grant access, but you should always carefully consider whether that access needs to be granted, or whether the function / class that needs it would be better off as a member of your class, instead.
Don't forget about testing and/or copying...
Friend classes / methods can be used quite successfully for checking intermediate states within class functionality.
They can also be useful for some types of copy constructors, where the class to be copied is not a direct ancestor of the target class thus precluding protected members as an option.
Consider the following use-case that I encountered recently: I refactored some code from one class into another class. This new class had to access members from the original class but I did not want to provide this via public getters to avoid other clients messing around with these. In this case, I really welcomed the C++-friendship mechanism.
However, these use cases are very seldom (hopefully, otherwise there is probably something wrong in your SW architecture) and I try to avoid it as much as I can since it is the tightest form of coupling.

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.)

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.

C++ subclass access

I have a main class that is inherited by numerous subclasses. The inherited main class has to be at least protected in inheritance to prevent non-derivative classes from using or altering it via the subclasses.
Is there a way to permit the various subclasses to alter each other's inherited main class variables, but without permitting public access to the main class? And without using the friend keyword given this would produce complicated code.
In full context:
I have a node class that add/remove nodes relative to it. There is a list class (and subclasses) that rely upon the node class, which means the node cannot be publicly accessible in-case it also breaks the class list. Node has to also be accessible to list helper classes.
To ensure that occurs, I implemented node under protected inside another class, accessnode. All classes wanting rights to node inherit accessnode as protected (so the accessnode class isn't public). This means the helper and the list class/subclasses all gain access to node.
The problem is, in order for TemplateList to copy CharList (a subclass of TemplateList) via read-only, it needs access to the nodes of CharList (to avoid using CharList's iterator) - the problem is, the nodes are protected (to prevent external, non-accessnode interference), and implementing a public method that grants access to the nodes would defeat the point.
What I need is sideways inheritance, so all subclasses of type accessnode can access each other's node without granting access publicly.
In short:
(Protected)Node inside AccessNode.
TemplateList : Protected AccessNode.
CharList : Protected AccessNode.
TemplateList needs to access CharList's AccessNode.
AccessNode/Node cannot be public.
Disclaimer: This is quite unrelated to this particular question, but more on the general problem that lead you to this and the other questions from today.
I think that you are barking at the wrong tree here. I get the feeling that you provide access to your list's internal nodes, and then expect that the node type itself protects the list from careless modifications (i.e. those that could break the invariants of the list). In doing so, you are pursuing a complex solution to a much simpler problem: do not let users access the node in the first place.
Things become much simpler if you look at the approach provided by the STL regarding containers and in particular lists. The list is implemented in terms of some unknown innaccessible nodes. The access specifiers on the operations of those nodes don't matter at all, since users cannot gain access to the object itself, so they can be public. Users gain access to the contents of the list through a different proxy (iterator, const_iterator types) that provides only those operations that cannot mess the state of the list.
I'm not completely sure I understand what you mean by "subclasses [to] alter each other's inherited main class variables".
If you want to allow access to a base class member variable by derived classes only then make the member variable protected. And/or add a protected accessor function.
If you want different instances of the derived classes to modify shared data held in the base class then you could add a static protected member variable to the base class. All instances would share the same member variable.
It would help if you clarified the problem.
You can always just add a protected accessor function in the top level class, but rather than do that it would probably be much better to rethink the design.
EDIT: concrete example:
class Base
{
protected:
struct State
{
int m1;
char m2;
State(): m1(), m2() {}
};
State state_;
static State& state( Base& o) { return o.state_; }
};
class Derived
: public Base
{
public:
void foo( Base& other )
{
Base::State& baseState = state( other );
// Blah blah.
}
};
int main()
{
Derived o;
// Blah blah.
}
Cheers & hth.,

How are classes more secure than structures?

Structure's member are public by default ans class's members are private by default. We can access private data members through a proper channel (using member function). If we have access to member functions we can read/write data in private data member, so how it is secure...we are accessing it and we are changing data too.....
Access specifiers, such as private and public have nothing to do with security. In C++, for example, these specifications get compiled away and don't even exist in the compiled binary.
Rather, access specifiers are designed to make types easy to use correctly, and difficult to use incorrectly.
There are only two syntactic differences between class and struct:
In a class, members and base classes are by default private, whereas in a struct, they are public by default.
For historical reasons, class can be used instead of typename to declare a template type parameter.
In fact, there's no difference between
struct X {
void f() {}
private:
int i;
};
and
class Y {
int i;
public:
void f() {}
};
The only way that a class is more "secure" than a struct is that it gently "presses" you towards better encapsulation by defaulting to private members.
There really was no need to introduce a new keyword class, Stroustrup himself said that on a few occasions. (Read his book The Design and Evolution of C++ if you're interested in such things.) Basically, class was introduced to emphasize the fact that a struct with member functions isn't really a "structure" anymore in the way the term was used in C: a collection of loosely coupled objects of built-in types. It's a "class" in the sense the term is used in statically typed object-oriented languages, even though syntactically, it's no real difference from a struct.
primarily because the member functions can validate the values before storing them. eg say you have a field called 'age', which must be between 0 and 150. in a structure (or a class with a public field), you could just do obj.age = 200. whereas if you only had a setAge(int) method, that method could sanity check the value is between 0 and 150 before storing, possibly throwing an exception if necessary or just clamping the value if not.
the public/private/protected keywords are not meant for security but rather for encapsulation. you design your class by separating the implementation (where the private/protected members are used - those actually used to implement the functionality) from the interface (where you expose the public members - which users of the class -other objects- will access/call) and thus you are later able to change the private parts without changing the interface. the outside objects only need to know about the public members and use these safely regardless of the implementation.
if you are speaking about security, think that anyone could change the private members of your class if they really wanted to and knew the internal structure of the class , just by overwriting the appropriate memory locations with new values - but the problem here is not about security, it's at a lower level
Taking that classes and structs are exactly the same besides the default access, the question is how encapsulating the internal representation from the interface helps build more robust code.
The main difference is that you control when and how your class data is modified, and as such you can control your class invariants. Consider a simple vector class that has a pointer and a size. By having them private you can control how they change: if the resize method is called, both the pointer and the internal size variable will be coherently updated, keeping the invariant that accessing any position in the range [0..size) is well defined. If the member attributes were public, user code would update the storage or size without actually updating the other field, and that invariant could be broken.
Many classes have internal invariants for the correct usage. If you write a class that contains a string with user email addresses, by providing an accessor method you can control that the value passed in is a valid email address, while if the email field was public user code could reset it to anything...
The whole thing is that you control how your members are accessed and modified and that reduces the number of places where mistakes can be made and/or your chances of detecting it.