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.,
Related
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.
Well there is enough information about this subject. For example this thread was very clear to me: Difference between private, public, and protected inheritance
Except one point; Why is it useful?
Use public inheritance to reflect an is-a relationship. This is the main use for inheritance, especially in combination with virtual functions. It allows re-use of interface, not just of old code by new code, but also re-use of new code by old code! (because of virtual function dispatch at runtime).
In exceptional circumstances, use private inheritance to reflect an is-implemented-in-terms-of relationship. This is a commonly overused pattern, often the equivalent goal can be reached through composition (having the would-be base class as a data member). Another drawback is that you can easily have multiple inheritance of the same base class (twice or more removed) leading to the so-called Diamond Problem.
Avoid using protected inheritance, it suggest that your class interface is client-dependent (derived classes versus the world). Often this is due to classes having multiple responsiblities, suggesting a refactoring into separate classes is appropriate.
The answer to this question concerns class interfaces and data encapsulation, rather than language capabilities.
The use cases of protected and private inheritance are rather limited, since there are often other options available which better solve the problem (such as using composition, rather than inheritance). However, there are times when you necessarily must inherit from some type (for example to interface with a third-party library), but you would strongly prefer (for reasons related to user interface of your class) to hide most members inherited from the base class from the users of your new type. A typical scenario would be when you need your type to have the member functions of a certain class for internal use, but it would break the logic of your new type if it was called from outside the class itself.
In these situations, you need to use private or protectedinheritance (depending on whether the interface should be similarly restricted to further derived classes or not.
Bear in mind, however, that this is all just about (strongly) hinting to the users of your class how they should use it. You're adapting its public interface to hide certain features which were public in its base class. This doesn't strictly speaking prevent people from accessing these members, since anyone can still cast a pointer to your derived class to a pointer to the base, and reach the "hidden" resources that way.
It's all about Data Encapsulation.
http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
Encapsulation concept
It is good to protect your classes 'internal' data from other classes. Benefits include:
other classes have to go through the known proper access mechanisms (e.g. methods) to access your class and can't monkey around with the internals of your class directly (and hence potentially put your class into some unknown and broken state)
you can change the inner workings of your class and know that other classes won't break as a result
reducing visible external points of contact with a class makes your classes simpler to use and understand
Having the option of using protected instead of private also makes your code easier to extend through subclassing.
Private: private members of a class can be accessed only from class functions, constructors, and destructors. The client who will use your class will be unable to access them. So, if for example you are implementing a list class and you want to keep track of the list's size, then you should have a private variable (listSizeP for example). You do this because you don't want the client to be able to modify the size of the list without inserting elements.
Public: public members can also be accessed by the client. In the list example mentioned above, functions like insert and erase should be public.
Protected: protected members of a class, like private members, can be accessed only from class functions, but they can also be accessed by classes inherited by this class(actually it depends on the way the derived class inherits the base. If it is not public inheritance, then the derived class cannot access the private members of the base class. That's why the most common way of inheriting is public inheritance). Example:
#include <iostream>
using namespace std;
class Base {
public:
int num;
public:
Base(int x=0) : num(x) {}
};
class Derived : public Base {
public:
Derived(int x=0) : Base(x) {}
void tell() { cout << "num: " << num << endl; }
};
int main() {
Derived D(4);
D.tell(); // would cause error if num was private
return 0;
}
Bjarne Stroustrup once said that he can address most of the tasks with ONLY private or public member variables and he seldom uses protected member variables in his design. I have heard similar arguments in other places. Here is an example,
class BaseClass
{
...
private:
int m_iAge;
double m_dSalary;
string m_strName;
bool m_bGender;
}
class SubClass : public BaseClass
{
...
}
Given the above class design, how the subclass SubClass can use the variables defined in BaseClass?
Question1> Why we should prefer to having private rather than protected variables? Is it the reason that the BaseClass can hide the implementation detail and make it easy for further improvement?
Question2> In order to let the SubClass access the variable defined in BaseClass, it seems to me that we have to define public access(get/set). However, getter/setter are evil! So the second choice is to define protected access(get/set). Any better idea?
Thank you
Bjarne's point is that generally the derived class shouldn't access the variables of the base class -- doing so frequently leads to maintenance problems. And no, changing it to use get/set (accessor/mutator) functions isn't an improvement.
Ask yourself - why would the derived class ever change the value of m_bGender? Or m_iAge? Doesn't the base class already handle these values correctly?
See, there is generally no need to have direct access to the internals of the base class. So we make them private, and use the class' public interface.
In some very rare cases, there might also be one or two protected functions, if derived classes need some special interface. But that is unusual. If derived classes have different behaviour, we more often use virtual functions for that.
I think the rationale for this claim is that in many situations, subclassing doesn't often change the behavior of the existing (inherited fields), but rather one adds fields and adds new methods that manipulate the new fields.
If you are looking for a way to manipulate inherited members w/o protected, you can, in the base class, make the derived class a friend. You would have to know it ahead of time, though.
The only main reason to use private over protected members is if they indeed are not required in child implementations. That's why we have protected members, because there are cases where the child class does need direct access to members of a parent class. I think Stroustrup is referring to a design whereby there is little need to access parent members in the first place, and child classes simply build upon the functionality of their parent rather than modify the functionality of their parent.
However, getter/setter are evil!
Why so? Getters and setters are an important part of OOP from my experience. There are good reasons to make an interface with a class, rather than access its variables directly.
I have a class Node. This class can add or remove other nodes relative to itself. Node is used by a List class. To prevent the nodes being modified directly (externally, IE not by the appropriate classes) during usage and causing problems with the List class, the nodes add/remove functions are either protected or private. This requires that List class is a friend to Node.
However, the problem with this is that the List class itself is a template class for other subclasses, and adding prototyping/adding the friend keyword for each subclass is clearly not the best solution.
How would I design the Node and List class/subclasses so that:
Node cannot be constructed by itself externally, is only constructed with specific classes/subclasses?
Node can construct/remove other nodes given above?
Node functions are only accessible to specific classes (List, list subclasses, and list helper classes - list helper classes are not subclasses of list)?
The node variable (Item) is publicly accessible give above?
List, list subclasses and list helper classes can directly modify or indirectly modify the non-public variables of Node?
Are these possible, and if so, how?
The standard library’s std::list class template is an example of how to design a list class so that no access to the internal nodes etc. is given to the client code.
With no access, no undesired meddling…
However, in general, it's more practical to trust a little, to not take it upon your shoulders to ensure that others’ code will be correct. It is a lot of work to express all the usage restrictions in C++. Opening up just a little can save a lot of work – so it’s a trade-off.
Cheers & hth.,
I would make Node a protected nested class of List:
class List
{
...
protected:
class Node
{
...
};
};
This way, only List and its subclasses can access it. Since it is nested within List, list may access its private/protected members and functions. It also helps to highlight the functional relationship between the two classes. This probably takes care of all your dot points except the third.
EDIT double checking my facts, it seems that in C++ enclosing classes do not have special access permissions to nested class members after all (seems that's a Java thing), see here. As such, you will need to make Node members public, but I still think this solution encourages good encapsulation.
I am not sure that I understand the problem in question, so instead of providing an answer I will provide with different approaches:
Have list be the only friend of node, and ensure that it offers all the operations that types deriving from list will need as protected methods. In this approach, the list type serves as a proxy to the node class for all of is derived types.
Have node be a protected internal type to list. The fact that it is internal to list and it is protected locks everyone outside of the hierarchy of list from using the type at all, all of the methods in node can be public.
Be friendly and trusty: leave the design as it is, and make some of the operations in node public to all. Trusting the users with the contents and document the invariants on which your list class is built so that user code will know what operations not to perform.
I prefer the first option, as it provides the list with the responsibility of managing the nodes, which is a good thing, at least better that sharing responsibilities... there is a single point where things can go wrong: the list class, and it is up to that class to maintain its own invariants.
As an idea, using Mac's answer:
Declare a class called NodeAccess, NodeAccess contains the Node class declared under protected (like Mac's answer).
Declare the functions in node as public.
class NodeAccess
{
protected:
class Node
{
public:
void Function(){}
};
};
Then for every class that wants access to the node, they inherit NodeAccess as protected, which grants them and all other subclasses access rights to node within the protected ruleset, but prevents any other class from accessing node directly.
class Helper: protected NodeAccess
{
};
class OtherHelper: protected Helper
{
};
//etc
I just want to make sure I got the idea of public and private right.
Regarding the private access specifier, does it mean:
Only accessed inside the class
Cannot be accessed from the object of the class unless there are public class methods that can be used to access them (Can other objects use those public functions?)
No other object can access them
And for public:
Accessed from the object of the class
Accessed from any other object
Is that right?
private : Only member functions and friends of class can access it.
public : Can be accessed anywhere where the object has scope.
Answering the questions -
private:
Yes
Yes. (Can other objects use those public functions? With out having class relations, one object of class cannot communicate to the other's members. )
Friends has access to private members of a class. So, answer depends upon your class has friends or not.
public:
Yes
Depends whether the object has hierarchical relations to the member's class you are trying to access.
I think there is an issue of vocabulary to begin with.
In C++ (and most languages) a class is a type. You can think about it as a blueprint to actually build something.
it describes the attributes that are held
it describes the methods to operate on those attributes
it describes the restrictions that apply: this is the "accessibility"
An object is produced by actually instantiating a class, that is, building what the blueprint described. It is more or a less a bundle of attributes. You can have several objects of the same class as you can have several houses from the same blueprint: note that their physical location is different for obvious reasons :)
Now, on to the accessibility. There are 3 typical levels of accessibility: public, protected and private.
public, as expected, means that everyone is given access to either attributes or methods
protected is somewhat less trivial. It means that only the object, or its children, may access the attributes (bad idea*) or methods. (Plus, in C++, friends)
private means that only the objects of that class (and not their children) may access the attributes or methods (Plus, in C++, friends)
Note: whatever the level of accessibility, an object has unrestricted access to all the attributes and methods of any object of the same class.
(*) Even though it pops up now and there, it is generally a bad idea to use protected attributes. The point of encapsulation is to hide the details, not only for the sake of it, but because by precisely controlling who can access the data, we can ensure that the class maintains its invariants (simple example, an array where you would store the size separately, you need to ensure that the "size" really represents the number of items in the array, at all times). Note: this restriction does not apply when you can seal a hierarchy, like in C# for example.
Private members can only be accessed by member functions and static functions of the same class and by friends of the class. It does not matter on which object that function is called. So the case
class Foo
{
private:
void bar() {}
public:
void baz(Foo& var)
{
var.bar();
}
}
is perfectly legal.
That seems correct. Data members and functions marked public can be accessed from anywhere by anyone. Data members and functions marked private can only be accessed by the class and its friends. However, a member function of a class can access data with any access specifier, so a public function can read and write private data members (this is used universally in OOP).
In c++ data and fn are encapsulated as 1 unit.
We begin a program by writing
preprocessor directives
Then, class declaration
Followed by function(fn) declaration where we also specify the access modifier ( public, private or protected)
& finally the main () program.
If we declare a fn
Private:the data within an object of a class is only accessed by fn defined within it- (the object which has the data and the private fn)
Public:the data can be accessed by any fn
Protected:similar to private however data can also be accessed by sub-classes that inherit the properties of another class.
Example if class A inherits from class B, thenA is a subclass of B.