What's the difference between friendship and inheritance? - c++

Suppose there are two classes A and B:
class A {};
class B {};
In what aspects differ the two examples below?
Example 1:
class C : public A, public B {};
Example 2:
class C
{
//private
friend class A;
friend class B;
}

A friend can touch the private parts (pun only slightly intentional! ;) ) of whatever it is friend of, but nothing of A and B are part of C - it just means that "A and B can touch C's private bits"). Anything "less" than private is of course also available to A and B, so if C has protected or public members, that will also be available.
When you inherit, the A and B becomes part of C. Any private sections of A and B are not available to C. In the "is-a" vs. "has-a" nomenclature, C now is-a A and is-a B - in other words, it's inherited from A, so it "behaves like A from an interface perspective.

There are several big differences. Inheritance and friendship are very different.
With friendship, class C is NOT an instance of class A or class B. Therefore, if you have a function like:
void processMyClass(A* a);
you cannot pass it an instance of C whereas, if C subclasses A (publicly), it IS an instance of A.
With friendship, class A and B can touch all the private member data and functions of C. With inheritance, class C can touch the public and protected members of A and B.
Friendship is not inherited. This means, for example:
class D : public C
{
private:
void foo() {
// A and B cannot call this function
}
}

In the context you're using, to answer your question to the best of my ability, friends simply allow your classes to share protected/private data, while inheritance will do the same, except there'll be a deeper relationship, where the classes are one in the same (such as with casting).

While the answers you've gotten are reasonably accurate, I don't think they're really complete. In particular, although they explain what the difference between friendship and inheritance is, they don't really explain much about which you should use when, or how the difference affects your code.
The primary use of inheritance (in C++) is to define an interface in a base class, and implement that interface in each of a number of derived classes. The parts of the interface that a derived class must implement will normally be signified by pure virtual functions in the base class.
The primary use of friendship in C++ is to define something that forms part of an interface, but for syntactical reasons can't be a member function. One extremely common example is a stream insertion or extraction operator. To implement these as member functions, they'd have to be members of the stream class. Since we don't want to modify the stream class constantly, they're instead free functions that take a reference to a stream as their left parameter, and a reference to a (possibly const) object of the type they insert/extract as their right operand.
These don't necessarily have to be friends of the class--they can be written to use only the class' public interface. If you do that, though, it generally means the class is exposing more in its public interface than is otherwise necessary. The interface is no longer minimal, which tends to indicate a problematic design.
One note though: you can define a friend function inside a class definition:
class Foo {
// ...
friend std::ostream &operator<<(std::ostream &os, Foo const &f) {
// ...
}
};
At first this may seem strange (and syntactically it is, somewhat). Even though it's defined inside the class definition, the friend means that this is not a member function. At least in my opinion, this reflects its situation fairly accurately: conceptually, it's part of the class. It has access to private members, just like any other member of the class. The fact that it's a free function rather than a member function is purely an implementation artifact that has essentially nothing to do with the code's design.
That also points to another difference between friendship and inheritance: with inheritance, you're normally dealing primarily with member functions. Each member function still receives a this pointer, so each member function is directly associated with a specific instance of the class. Yes, you can define it to also receive (a pointer or reference to) another instance of the class if desired, but it always receives this, regardless. A friend (function or class) doesn't get this--the friend declaration just means that the names that are private to that other class are visible to the friend. To get access to an actual instance of that class, you typically need to pass it as a parameter, or something on that order.
Finally, I'll note that the preceding sort of ignores the possibilities of private or protected inheritance. Private inheritance normally means that the derived class is implemented in terms of the base class. This can be handy if (for example) the derived class is similar to the base class, but isn't related in the design--i.e., you're not asserting that an instance of the derived class can be used anywhere an instance of the base class was needed. Its use of the base class is an implementation detail that the rest of the world doesn't need to know or care about.
Protected inheritance is pretty much a mistake. It's allowed because it's consistent with public, private and protected members (which do make sense) but for inheritance, protected simply doesn't seem to accomplish anything useful.

Related

Is there a way to bring all definitions in a C++ struct/class into scope without deriving from it?

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

Using a function publicly in base class and privately in derived class

I have a function public void myFunction(foo); and public void myFunction(foo, bar); in my parent class. I want these functions included in my derived class, but privately. You can declare it in the derived class' private section by using BaseClass::myFunction(). Note that it doesnt take any parameters in the function. But if there are two implementations of myFunction like I have in my case, it won't work since it can't distinguish between the two functions. How do I implement both functions privately?
Based on what you've said in your comment about your professor's instruction to use inheritance, more than whether it's a good design choice, I think you are expected to use private inheritance.
Private inheritance is a valid feature of C++, but its often not a good design choice. I wont go into that, I'm not recommending it in general, I'll leave you to look it up elsewhere on SO, but also recommend Scott Meyer's books effective C++ & more effective C++ which covers this.
(protected inheritance on the other hand is very unusual)
In your question you seem to be starting from public inheritance and trying to make some inherited functionality private via using. This is a bad design choice as mentioned in comments. It violates the Liskov substitution principle. Since PUBLIC inheritance implies is-a, we can imagine the code that creates a base class reference to an object of the derived type, what then is supposed to happen when we try to call the hidden functionality with that base class reference?
Derived d;
Base& b = d;
b.HiddenFunction(); // calling the function on d even though you thought you hid it
If instead you use private inheritance you can then use using to publicise those privately inherited functions which are safe to expose on the derived class.
class OrderedLinkedList : private LinkedList
{
public:
using LinkedList::ItemCount; // expose some specific base functionality
};
If using doesn't do the job due to overloaded functions, then you can add just those overloads that you want to provide and implement them just by calling the base function. In such cases, if you need to clarify whether to call the base or derived version you can prefix the function name with the class name e.g.
void SomeFunction()
{
// call base version, not this derived version recursively
NameOfBaseClass::SomeFunction();
}
Within the derived class implementation, the public and protected members of the (privately) inherited base class are accessible without the need to do anything like add a using.
Private inheritance is not an is-a relationship like public inheritance since we cannot refer to the derived objects as references/pointers to the base. Private inheritance is "implemented-in-terms-of".
Since private inheritance is not an is-a, one cannot substitute such derived objects for the base and as such the liskov substitution principle just doesn't apply.

Need clarification on interface in OOP

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.

Why define Parent class as friend class?

I am looking at other's code and find one part I can't understand.
class a {
public:
function xxx () {.....}
}
class b : public a {
public:
xxxx
protected:
constructor()....
friend class a ; <= here why it is needed ????
}
As I understand, since b had already inherited from a, it should be able to use the function of a directly. What's the purpose of this "friend" declaration used for?
The friend allows a to use b's methods, not the other way around, which isn't implicit.
The design looks fishy though, a base class shouldn't care about derived classes.
friend class a; grants class a the right to access non-public members of b. So in this small example, an instance of a can call b::constructor(). Without friendship, it wouldn't be possible.
As to why, there is not enough information to answer that, other than there must be a need for instances of a to call b::constructor() (assuming that to be anything other than the syntax error it currently is).
As I understand, since b had already inherited from a, it should be able to use the function of a directly.
Yes. The friend specification though allows access the other way around (instances of a will be able to access private data and functions of b).
What's the purpose of this "friend" declaration used for?
The example above doesn't suggest any. The only situation where it may make sense is with using CRTP in certain situations (i.e. a is a template of b) but even so, if you see such a requirement ("must add friend declaration in b") it is possible that the design you're looking at is flawed.
Can you post a concrete example?
Depending on your projects/requirements, your class designs change. I have no comment on your class hierarchy but true your question is all about theories of friend usage. If you don't use friend, you will not be able to call B members from A. It is there for...cross-mating :D
It almost certainly means that there is a serious design problem. One of the basic rules of thumb for inheritance is that base classes should not need any information about derived classes. Making a a friend of b makes it possible for member functions of a to get at the internals of b 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.