One of the main design principles of C++ as an Object Oriented language is to let each class enforce who can access it's innards and who can't. A base class controls it's access levels even if it is with respect to a base class object embedded within a object of a class derived from Base.
However I read about using declarations that can be allowed to change the access level of a Base class member in a Derived class.
class A{
protected:
int n;
};
class B:protected A{
public:
using A::n;
};
int main(){
B obj;
obj.n=0;
}
In the example above, I am changing the access level of a protected member to public in the derived class. Is this allowed on purpose? Why couldn't it be enforced that the access level should be more stringent or equal to how it is in the base class (this can be controlled by the access qualification in the derivation list as well) but cannot be more relaxed than the access level in the base class? Is this allowed because this allows some interesting design patterns? I am just trying to understood why something like this which breaks the principle of encapsulation enforced by a class is allowed?
One reason is that this way you can even change the visibility modifier even if you are not the owner of the base class.
For example if the base class is included in an external library/framework you can change the visibility modifier.
Related
What are public, private and protected in object oriented programming?
They are access modifiers and help us implement Encapsulation (or information hiding). They tell the compiler which other classes should have access to the field or method being defined.
private - Only the current class will have access to the field or method.
protected - Only the current class and subclasses (and sometimes also same-package classes) of this class will have access to the field or method.
public - Any class can refer to the field or call the method.
This assumes these keywords are used as part of a field or method declaration within a class definition.
They aren't really concepts but rather specific keywords that tend to occur (with slightly different semantics) in popular languages like C++ and Java.
Essentially, they are meant to allow a class to restrict access to members (fields or functions). The idea is that the less one type is allowed to access in another type, the less dependency can be created. This allows the accessed object to be changed more easily without affecting objects that refer to it.
Broadly speaking, public means everyone is allowed to access, private means that only members of the same class are allowed to access, and protected means that members of subclasses are also allowed. However, each language adds its own things to this. For example, C++ allows you to inherit non-publicly. In Java, there is also a default (package) access level, and there are rules about internal classes, etc.
All the three are access modifiers and keywords which are used in a class.
Anything declared in public can be used by any object within the class or outside the class,variables in private can only be used by the objects within the class and could not be changed through direct access(as it can change through functions like friend function).Anything defined under protected section can be used by the class and their just derived class.
A public item is one that is accessible from any other class. You just have to know what object it is and you can use a dot operator to access it. Protected means that a class and its subclasses have access to the variable, but not any other classes, they need to use a getter/setter to do anything with the variable. A private means that only that class has direct access to the variable, everything else needs a method/function to access or change that data. Hope this helps.
as above, but qualitatively:
private - least access, best encapsulation
protected - some access, moderate encapsulation
public - full access, no encapsulation
the less access you provide the fewer implementation details leak out of your objects. less of this sort of leakage means more flexibility (aka "looser coupling") in terms of changing how an object is implemented without breaking clients of the object. this is a truly fundamental thing to understand.
To sum it up,in object oriented programming, everything is modeled into classes and objects.
Classes contain properties and methods.
Public, private and protected keywords are used to specify access to these members(properties and methods) of a class from other classes or other .dlls or even other applications.
These are access modifiers.
All the data and functions(behaviours) are encapsulated or bounded into a single unit called a class. In order to access the properties and behaviour of the class we use objects. But it's also important to decide which behaviour or property has to be exposed or should remain accessible to all the classes and which behaviour or property has to be private.
So, that's when access modifiers like public, private, protected and protected internal help in doing so. This act of defining privilege to the class or method or property is called as abstraction.
Musing on a Sunday...
Deriving from a class brings all names from the base class into the scope of the derived class. However, it also adds the base class non-static data members to every instance of the derived class.
Is there a way to achieve the former without the latter? I'm asking in the interest of concise notation.
Obviously, when the base class doesn't have any data members, I get what I want. There are quite a few empty classes or class templates in the standard library defined to do just that - inject names summarily into a class scope through inheritance. There's even the empty base class optimization to make this as cheap as possible.
But if I wanted to do the same with a non-empty base class, I would be tempted to employ something like:
struct Bar {
using struct Foo;
};
But, alas, that's not supported by C++. My question is, is there another way to achieve the same which I overlooked?
To provide a more complete example:
struct Foo {
enum { some_constant=42 };
// data members follow here ...
};
struct Bar {
using class Foo; // this doesn't compile
int f();
};
int Bar::f() {
return some_constant; // I want to use the constant directly, without Foo::
}
One clumsy way could be to split the definitions in Foo into two classes, one with the constants (which would be an empty class I could derive from without penalty) and the other with the data members, but that looks rather like an inelegant hack to me.
If there isn't a clean way to achieve this, maybe someone can provide a rationale for why it doesn't exist, or perhaps shouldn't exist.
Deriving from a class brings all names from the base class into the scope of the derived class.
Let me stop you there. Yes, it is true that inheriting from a base class causes the (non-private) names in the base class to be accessible from the derived class definition. However, that's not why you inherit from a base class; that's merely the mechanism by which inheritance achieves its goal.
To publicly inherit from a base class is to make a statement about the relationship between the derived and base classes. You're saying that every instance of the derived class should behave like the base class in virtually all ways. Even virtual function overriding still carries with it the expectation that the derived class implementations of these methods are conceptually doing the same job, just in a way appropriate for that derived class.
This is true even of mixin-style base classes, where the base class is used to define common functionality that is imported into a particular derived class. In such interfaces, there is little expectation of a user explicitly talking to base class definitions. But this provision of common functionality is ultimately still based on the semantic idea of a derived class being a base class. And that's very important for many of them to do their job.
Consider what is probably the most prominent mixin in the C++ standard library: std::enable_shared_from_this<T>. It has non-static data members, without which it couldn't actually provide the functionality it does (well, it could, but you would have to provide some interface in your derived class to store them, so it may as well do it).
This is true of private inheritance, though there is some modification. While to the outside world, the derived class is just a derived class, to the class definition itself, it still remains a base class. It remains wholly a base class, along with all the baggage that comes along with it.
Do not mistake the mechanism for the meaning. Mechanisms are important; don't get me wrong. But those mechanisms exist to facilitate meaning.
Having a class contain everything of some other class except the non-static data members is, semantically, nonsense. It doesn't mean anything about the relationship between the types. And you've essentially admitted that the main reason you want this is so that you don't have to scope-qualify the names defined in the "base" class.
This is a mechanical reason, not a semantic one. You shouldn't employ a semantic tool like inheritance to escape the mechanical consequences of how you have chosen to design your types.
In reference to your specific example you could make the constants you want to access static, which will allow you to access them from the second class by fully qualifying with the "base" class
With regards to a class, what does an interface mean? I think it refers to all the public functions of the class. Am I correct or does it mean something else?
I keep hearing it a lot but never quite noticed the explicit definition.
This one's the real question. What does it mean for a derived class to retain the interface of the base class it's derived from? I think it means that the public functions in the base class must be public in the derived class as well (which will be the case in public and protected inheritance). Am I mistaken?
Yes, the interface of a class is the collection of its visible member functions to the outside world, i.e. its public member functions. Some also include member variables in the interface, but it is not usually common to have public member variables (unless declared static). Most often, interfaces are implemented via abstract base classes. This is in contrast to Java, which has a different keyword for specifying interfaces.
Retaining the interface means having the public member functions in the base class visible across the class hierarchy. Also, you can override virtual functions so you get polymorphic behaviour, keeping the common interface. Note that only public inheritance preserves the interface, protected and private do not. Another way of failing to retain an interface is via name hiding in C++. Example: re-declaring Base::f(int) as Derived::f(float,float). In this case, the Base::f(int) is not longer visible in Derived, unless via a using Base::f; statement.
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.
If I'm creating an abstract base class, and the classes derived from it are going to have some of the same data members, is it better practice to make those members private in the abstract base class and give protected access to them? Or to not bother and just put the data members in the derived classes. This is in C++.
The main question to ask in an OOP setting is: Where does this data belong?
In an inheritance relationship, Data (and functionality) should be defined at the highest stage where it is more or less invariant. This promotes maximum modularity and code-reuse. For example, assume two classes:
class Human;
class Student : public Human;
When adding a data member 'm_Arms', we determine the 'Human' level as the best place to define the data, its usage and its visibility to the derived classes, based on the following questions:
Will specializations of humans require more-or-less invariant behavior from the human's arms? i.e. Will they be able to do something that a 'generic' human normally cannot? - (determining common data).
Will the student (or other possible Human specializations) require direct access to it? (determining visibility to child classes).
If visible, which functions are common? (determining associated common functions)
The context should be thought of from the base class's perspective - even if there is one additional is-a-Human class that can do something extra, then it needs to have access to the data. e.g. If for some reason, you decide class Robocop : public Human, you need access to his thigh directly to store the gun inside. Under this architecture, Thigh then needs to become visible to all child classes of Human.
The architecture can be refined using the same principles of data modularity, function modularity and visibility. For example, when defining the class Robocop, The base class Human can be further extracted as follows to allow a change in visibility, and consequent changes in functionality.
class Human;
class NormalHuman : public Human; //declare Thigh private here.
class SuperHuman : public Human; //continue using Thigh as protected.
Further, Arms may themselves be made polymorphic, allowing (excuse the unintended dystopic interpretation) factory-based architectures to modularly assemble different types of Humans using Human parts.
If the data belongs to the derived class, let the derived class do what it wants to contain that data.
By placing that data in the base class (not privately), you force every derived class to have it. The derived classes shouldn't be forced to do anything unless they need to fill out the data member, for example. The base class defines what derived classes must do, not how they should do it.
If you find there might be a common theme, you can make a derived class that has those members and implementations, which is then intended to be the base class for those that want to use it. For example:
struct car
{
virtual ~car(){}
virtual unsigned year(void) const = 0;
virtual const std::string make(void) const = 0;
}
// Dodge cars can feel free to derive from this instead, it's just a helper
struct dodge_car
{
virtual ~car(){}
virtual unsigned year(void) const = 0;
const std::string make(void) const
{
static const std::string result = "Dodge";
return result;
}
}
And so on. But you see, any derived classes still have the choice of implementing the entire car interface. This also improves code cleanliness. By keeping your interface a real interface, implementation details won't get in the way.
Any variables your base class uses should be private, because derived classes don't need to know how it works, in the same way users of your derived class don't need to know how the internals of the derived class work.
How can you make members private and give protected access?
Derived class cannot access base class' private members.
Would Derived class A and Derived class B both need those data members you are talking about? If yes, then put them in base class and make it protected yes.
I know, I actually wanted to post a comment, but I don't know how. May be I need more reputation?
Don't think about what some of your derived classes would do, think about what all of them must do, when writing the base class. In other words, think about the base class itself and the guarantees it makes—its interface.
C++ doesn't have a separate concept of "interface definition" and just reuses classes for that. (Or duck typing in templates.) Because of this, be careful how you write your abstract interface classes so you don't impose restrictions on implementations.
I'm not answering either yes or no because you haven't given enough information, and the answer depends on those other details; but if you follow the guidelines I've briefly laid out, you'll be in decent shape.
There's nothing wrong with having some of the data (and of the implementation, i.e. methods) in the base class.
The base class could be virtual by the mere fact that only one of its methods must be implemented in derived class. The decision of making these variables and methods [of the base class] private, protected or even public, is a case by case issue.
For example the base class could have a public method, a protected method and/or data, and a few private methods.