Does inheritance break encapsulation in C++ - c++

I read (Scott Myers) that inheritance breaks encapsulation. When data/internal methods are private (not protected), is encapsulation broken?
e.g.
class Vehicle
{
int color;
public:
void set_color();
int get_color();
}
class Car: public Vehicle
{
public:
void change_tires();
}
I can change the internals of Vehicle without breaking Car ever knowing, correct?

Phrases like "inheritance breaks encapsulation" are often taken out of context.
What the phrase refers to is the fact that the virtual interface being inherited is now not encapsulated. In effect, inheritance means that certain things that were hidden are now exposed. Things like protected members and virtual private members are all open for play by derived classes.
Non-virtual private members are still hidden.

Well, I dont know what Scott Myers said, but anyway, by doing the way you specified, a car method can only access the Vehicle public methods and properties exactly the same way that you would be able if you created a Vehicle object (there are no protected methods and properties), so there are no encapsulation breaking over here, only if the base class is not correctly encapsulated. You will only be able to change the color of the Car by using set_color(...) method, since int color is private (class properties and functions are private if not specified).

Related

Does multi-layer inheritance make sense in C++?

I use 3-layer inheritance design below:
class connect_info {
// these members
};
class vertex : public connect_info {
// ...
};
// user-defined struct
class algo_vertex: public vertex {
// ...
};
members of connect_info class(I call it these members in this question) is only used in vertex class. But to keep the semantic of vertex class clear, I must separate these members to another base class(connect_info).
Problems generate here:
how can I hide these members from user-defined class? (protected and private are both useless now. If there is no connect_info base class, private can work well)
Does multi-layer inheritance design make sense in any situation?
Can virtual de-constructor function work well in multi-layer inheritance case?
You might need to move to has-a relationship, where connect_info can be an internal class(A class inside class) and make it private, if you want to hide connect_info members in user defined class.
class vertex {
// ...
private:
class connect_info{/*these members*/};
};
class algo_vertex : public vertex{
// connect_info members no longer accessible,
// unless you provide member functions in `vertex` to access it.
};
Inheritance is introducing strong coupling between classes, and is generally avoided. Instead, people are using composition. Read Prefer composition over inheritance question and answers.
In your specific example, what do you do, when you add algo_B_vertex class, where some of fields and methods from Vertex make no sense. Or in worse case scenario connect_info. Then you get into all sorts of problems. Not to mention complexity of several layers of inheritance.
how can I hide these members from user-defined class?
By using composition, and creating objects in private section.
Does multi-layer inheritance design make sense in any situation?
Of course it does. Fortunately that number of such situations is little. General advice is to think twice before jumping into multiple inheritance.
A good trade-of here would be to make vertexinherit privately from connect_info. The big difference with composition is that within the class vertex you can consider yourself being a connect_info, which means you will be able to access these members by doing this->member instead of connect_info_attribute.member. Also you won't need any friend or encapsulation hacks.
To sum it up, from the point of view of the child class, private inheritance means i consider myself being a "parent" but i don't want anyone else (not even my children) to consider me like one.

Confusion about inheritance & access level

I've got some confusions on the access level in C++ inheritance and more generally how I should design a C++ class.
class Car
{
public:
private:
string brandName;
}
class Sedan: public Car
{
public:
// this function needs to know the Sedan's brandName
void someFun()
{
brandName = "sss"; // error!!!
}
private:
}
In the above example the Car as a base class has a private member "brandName", and the Sedan as a derived class from Car inherits that member "brandName". As explained in Effective C++, public inheritance makes an "is-a" relationship, which means Sedan is a Car, now can I say that Sedan has a "brandName"?. If the answer is yes, why couldn't Sedan access to its own attribute in someFun?
I know the solution is to change brandName's access level to protected, my confusion is that what features or conditions make a variable member to which access level, in other word how I decide which access level should a given member be attached to?
I'd also like it if you'd recommend any book or article elaborating on this topic.
now can I say that Sedan has a "brandName"?
No, neither has Car. The brandName is an implementatin detail, private, hidden from anyone else and does not contribute to the class' public interface, which is what makes the nature of a Car. So while technically there is a brandName somewhere in a Car and thus in a Sedan, from a pure OO view that does not matter. Similar to "Is-A"-relationships that are expressed only by public inheritance and not by private inheritance, "Has-A"-relationships in the OO point of view are only present if the composition or assoctiation is publicly accessible/visible (mostly via getters/setters).
juanchopanza's answer and the comments to it have lead me to sneak a little around the web, trying to find resources about Is-A and Has-An relationships. this transcription seems to indicate that the two terms did not originate from OO thoughts. In fact, OO literature seems to cite the Liskov Substitution Principle instead of using "Is-A" relationships. It lays stress on encapsulation and opaque objects, so it concerns mostly with public interfaces of classes and how their behavior affect associated objects. While a "Has-A" relationship can be association, it also can be aggregation. In this case, since the brandName is not an external, associated object (in C++ we would express that fact with a pointer or reference member), it is an aggregation-"Has-A", hidden in the opaque Car and therefore not of interest for OO (and the above answer is left semantically valid).
I know the solution is to change brandName's access level to protected
NO! brandName's access level has to remain private, so that Car has the complete control over what happens to it. If you want to access it in derived classes, provide protected getters and/or setters.
I'd also like it if you'd recommend any book or article elaborating on this topic.
Any book about object oriented design should do. If you read through two or more of them, you will get a good idea of what to do and what not to do.
can I say that Sedan has a "brandName"?.
Yes, it certainly has an object of type string called Car::brandName (whether this constitutes an OOP "has-a" relationship isn't entirely clear to me, but probably not: see comments)
If the answer is yes, why couldn't Sedan access to its own attribute in someFun?
Simple because brandName is private. Those are the rules of the language. If you want to give a derived class access to a non-public data member, you can make it protected.
I'd also like it if you'd recommend any book or article elaborating on this topic.
There is a list of books here. Perhaps "The C++ Programming Language" would be good for explaining this particular aspect.
you have hidder brandName from the outer world, by making it private. Make it protected so that children may inherit it. To understand inheritance rules regarding specifiers, go to HERE
Public members are free to all to use.
Private members are for the use of only this current class, and no one else. It is used mostly for inner members of the class to use and save for it's own purposes or to provide a method to access to them.
Protected members are accessible for inherited classes, just as your example shows - brandName is for the use of inherit classes, so it should be protected.
I've got some confusions on the access level in C++ inheritance and more generally how I should design a C++ class.
C++ has three access level specifiers that can be used when inheriting:
private, protected and public
class Derived : public Base
Is called public inheritance and represents IsA relationship. When inheriting publicly, public members of the base remain public in Derived, protected members remain protected in Derived and private members are private (and not accessible from Derived).
class Derived : protected Base
Is called protected inheritance. This kind of inheritance is rare, and would be used if you don't want to expose the public part of Base when accessed as derived (or through the interface of Derived). In this kind of inheritance the public members in base become protected in derived.
Also see the C++ FAQs
class Derived : private Base
Is called private inheritance. This kind of inheritance can be used to simulate containment (Herb Sutter - Uses and abuses of inheritance). Here public members in Base become private when accessed through the interface of derived.
It can also be noted that protected and private inheritance does not represent the classic IsA relationship. The following polymorphic behaviour is only possible when inheriting publicly:
Derived d;
Base* b = &d;
However, for private inheritance polymorphic behaviour is possible in the first derived class (but not in subsequent).
struct Base{};
struct Derived : private Base
{
Derived()
{
//IsA holds within member functions of Derived, but not
// outside
Base* b = this;
}
};
struct Derived2 : public Derived
{
Derived2()
{
Base* b = this; //Fails to compile...inaccessible base
}
};
int main()
{
Derived d;
Base* b = &d; //Fails to compile
}
For protected inheritance polymorphic behaviour is possible in the all subsequent derived classes (Therefore code in constructor of Derived2 here above would compile), but not outside of class member functions.
Herb Sutter comments on reasons for using non public inheritance in Uses and abuses.
Finally, a comment concerning your example above: Usually Car would be abstract (an interface, consisting only of pure virtual functions), and therefore it would not contain any data members, but leave it open to the implementation. This is a guideline concerning inheritance that I've heard somewhere Sutter - Exceptional C++:
Inherit publicly in order to be reused by code that uses base classes polymorphically.
Your example would/could become:
struct Car
{
//Note: const used as brandName should not modify logical state.
virtual const std::string& brandName() const = 0;
//...virtual ~Car(), amongst others, depending
// on whether you intend to be deleted via this interface...
};
// Note: public inheritance implied by struct
struct CarFromFile: /*public*/ Car
{
CarFromFile( std::ifstream& file )
: brandName_( strFrom( file ) ),
manufacturer_( strFrom( file )
{
}
virtual const std::string& brandName() const{ return brandName_; }
private:
std::string strFrom( std::ifstream& file )
{
std::string value;
if( file >> value ) { return value; }
throw std::runtime_error( "Invalid file format!" );
}
std::string brandName_;
std::string manufacturer_;
//etc...
};
The fact that you make the accessor abstract, allows freedom from
the perspective of the implementer of derived, and defines the service
required by the client of base, independent of how the actual data looks.
The classifications for public, protected and private are intended to allow one to separate publicly available interfaces from internal implementation details. Thus, things that are not public are inaccessible, forcing users of the class to use the public interfaces provided.
If something is private, then even though inheritance will make the member a part of the derived class, the derivation is not allowed to access it. If it is desirable to allow a derived class access to interfaces and members that are not part of the public interface, then that is exactly when to use protected.

C++ why use public, private or protected inheritance?

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;
}

Private virtual method in C++

What is the advantage of making a private method virtual in C++?
I have noticed this in an open source C++ project:
class HTMLDocument : public Document, public CachedResourceClient {
private:
virtual bool childAllowed(Node*);
virtual PassRefPtr<Element> createElement(const AtomicString& tagName, ExceptionCode&);
};
Herb Sutter has very nicely explained it here.
Guideline #2: Prefer to make virtual functions private.
This lets the derived classes override the function to customize the
behavior as needed, without further exposing the virtual functions
directly by making them callable by derived classes (as would be
possible if the functions were just protected). The point is that
virtual functions exist to allow customization; unless they also need
to be invoked directly from within derived classes' code, there's no
need to ever make them anything but private
If the method is virtual it can be overridden by derived classes, even if it's private. When the virtual method is called, the overridden version will be invoked.
(Opposed to Herb Sutter quoted by Prasoon Saurav in his answer, the C++ FAQ Lite recommends against private virtuals, mostly because it often confuses people.)
Despite all of the calls to declare a virtual member private, the argument simply doesn't hold water. Frequently, a derived class's override of a virtual function will have to call the base class version. It can't if it's declared private:
class Base
{
private:
int m_data;
virtual void cleanup() { /*do something*/ }
protected:
Base(int idata): m_data (idata) {}
public:
int data() const { return m_data; }
void set_data (int ndata) { m_data = ndata; cleanup(); }
};
class Derived: public Base
{
private:
void cleanup() override
{
// do other stuff
Base::cleanup(); // nope, can't do it
}
public:
Derived (int idata): base(idata) {}
};
You have to declare the base class method protected.
Then, you have to take the ugly expedient of indicating via a comment that the method should be overridden but not called.
class Base
{
...
protected:
// chained virtual function!
// call in your derived version but nowhere else.
// Use set_data instead
virtual void cleanup() { /* do something */ }
...
Thus Herb Sutter's guideline #3...But the horse is out of the barn anyway.
When you declare something protected you're implicitly trusting the writer of any derived class to understand and properly use the protected internals, just the way a friend declaration implies a deeper trust for private members.
Users who get bad behavior from violating that trust (e.g. labeled 'clueless' by not bothering to read your documentation) have only themselves to blame.
Update: I've had some feedback that claims you can "chain" virtual function implementations this way using private virtual functions. If so, I'd sure like to see it.
The C++ compilers I use definitely won't let a derived class implementation call a private base class implementation.
If the C++ committee relaxed "private" to allow this specific access, I'd be all for private virtual functions. As it stands, we're still being advised to lock the barn door after the horse is stolen.
I first came across this concept while reading Scott Meyers' 'Effective C++', Item 35: Consider alternatives to virtual functions. I wanted to reference Scott Mayers for others that may be interested.
It's part of the Template Method Pattern via the Non-Virtual Interface idiom: the public facing methods aren't virtual; rather, they wrap the virtual method calls which are private. The base class can then run logic before and after the private virtual function call:
public:
void NonVirtualCalc(...)
{
// Setup
PrivateVirtualCalcCall(...);
// Clean up
}
I think that this is a very interesting design pattern and I'm sure you can see how the added control is useful.
Why make the virtual function private? The best reason is that we've already provided a public facing method.
Why not simply make it protected so that I can use the method for other interesting things? I suppose it will always depend on your design and how you believe the base class fits in. I would argue that the derived class maker should focus on implementing the required logic; everything else is already taken care of. Also, there's the matter of encapsulation.
From a C++ perspective, it's completely legitimate to override a private virtual method even though you won't be able to call it from your class. This supports the design described above.
I use them to allow derived classes to "fill in the blanks" for a base class without exposing such a hole to end users. For example, I have highly stateful objects deriving from a common base, which can only implement 2/3 of the overall state machine (the derived classes provide the remaining 1/3 depending on a template argument, and the base cannot be a template for other reasons).
I NEED to have the common base class in order to make many of the public APIs work correctly (I'm using variadic templates), but I cannot let that object out into the wild. Worse, if I leave the craters in the state machine- in the form of pure virtual functions- anywhere but in "Private", I allow a clever or clueless user deriving from one of its child classes to override methods that users should never touch. So, I put the state machine 'brains' in PRIVATE virtual functions. Then the immediate children of the base class fill in the blanks on their NON-virtual overrides, and users can safely use the resulting objects or create their own further derived classes without worrying about messing up the state machine.
As for the argument that you shouldn't HAVE public virtual methods, I say BS. Users can improperly override private virtuals just as easily as public ones- they're defining new classes after all. If the public shouldn't modify a given API, don't make it virtual AT ALL in publicly accessible objects.

Abstract Base Class with Data Members

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.