I am documenting a few classes with Doxygen.
My class graph features a generic base class which is inherited by others. I do want the members of the base class to be listed in the derived classes (in a "Public members inherited from…" section). But I don't want the base class to appear stand-alone.
If I uncomment the base class and activate the HIDE_UNDOC_CLASSES flag, the base class completely disappears, even in the inherited sections of the derived classes, even though I left comments on the base members. This is not what I want.
Do you know a way to achieve this effect ?
Related
I need to write an abstract class that defines an interface.
All its methods are pure virtual ones.
Now, there are a few members that should be in that class as well, and my question -
is it a good c++ practice to add them in this class or should I define a new class (let's call it: class members) that contains those members, and the derived class will inherit from both: the interface class and the member class.
thanks
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
In composition, one class explicitly contains the other. However in Inheritance, the base class is implicitly contained in the derived class. Correct or not? I ask this because after several days of studying inheritance, it's only today that I got to read somewhere that an object of a derived class always contains an object of it's base class.
I mean, I thought that there would be only one object and just the functionality would be inherited but I didn't know that it would also contain an object of the base class within.
In Composition, one object contained another object. While in inheritance, your object is acquire properties of base class.
I mean, I thought that there would be only one object and just the
functionality would be inherited but I didn't know that it would also
contain an object of the base class within.
Yes you are right, there will be only one object and functionality is getting inherited. Even if your base class have member variables, there size will getting added to your object size.
You can directly call public and protected methods of base class. While in cointainership you are only able to access public methods.
That's should be:
In composition, one class explicitly contains an object of the other class. However in Inheritance, the base class is implicitly contained in the derived class.
In short:
Composition is about the relationship of class and object.
Inheritance is about the relationship of class and class.
And please remember "Prefer composition over inheritance".
Prefer composition over inheritance?
In general derived class contains all data members and shares the properties/methods of base class, but there is a difference between composition and inheritance.
By "composition" you mean that one object "has" some other object. In example: human has a liver. In class design it can be presented like below:
class Liver {};
class Human
{
public:
Human() {}
private:
Liver mLiver;
}
When talking about an inheritance, there are 2 options: public inheritance roughly says that one object "is" a kind of other object. In example: Human is a kind of living creature. It does not sound naturally to say that human "has" a living creature inside. Public inheritance is a way to go in such case:
class LivingCreature {};
class Human : public LivingCreature
{
public:
Human() {}
}
Other option is protected/private inheritance, which should be used to implement some object "in terms of" other object. Generally it can also be treated as kind of composition, but first approach is usually better.
Summarizing:
If you can say that one object "is" a kind of other, more general object: public inheritance is the best way to go,
If you can say that one object "has" other object: use composition.
Consider the code:
class Engine
{
//Some Code
};
class Vehicle
{
//Some Code
};
class Car:Vehicle
{
Engine engine;
//Some Code
};
In this case class Car inherits the class Vehicle. An object of the class Car doesn't contain an object Vehicle, rather it is an object of the class Vehicle (Inheritance). On the other hand it does contain an object of the class Engine(Composition).
The fact that you can access a parent's function with this comes from the fact that the Car object is a Vehicle not because it contains an Vehicle object.
In composition, one class explicitly contains the other. However in Inheritance, the base class is implicitly contained in the derived class. Correct or not?
It's entirely a matter of knowledge/perspective: if you're aware that inheritance means a base class instance will be embedded in the derived class then saying class Dervived : Base can be seen as explicitly requesting that, while if you're aware that defining a variable inside class X means it's a member variable that will be contained in instances of X, then that can be seen as explicit too.
I ask this because after several days of studying inheritance, it's only today that I got to read somewhere that an object of a derived class always contains an object of it's [sic] base class.
The distinction between actually containing a base class object vs. through some more unspecified/mysterious means being substitutable for a base class instance on occasion, isn't necessarily the most important thing when starting to learn about inheritance, so it's easy to imagine it isn't emphasised in all learning material.
I mean, I thought that there would be only one object and just the functionality would be inherited but I didn't know that it would also contain an object of the base class within.
At an implementation level, it's important that it actually contains a base class instance, so code compiled to handle base class objects can work equally well on derived class instances. The C++ Standard could have deemed it merely an embedded copy of base class content with identical binary layout while not an actual base class object, but then a huge amount of text in the Standard would have to be added to mention that the derived objects could be used in scenarios where a base class instance was acceptable. In other words, the distinction is somewhat arbitrary, but it's easier for everyone if it's both intuitive and lends itself naturally to simpler, more concise Standard wording.
Inheritance vs Composition:: Is my understanding correct?
Conceptual differences:
Inheritance:
In case of inheritance, derived class is sub-type of base class.
Meaning if you derive Dog from Animal, then Dog is Animal and
all* operations that can be performed on Animal can be performed on Dog.
Using private, protected and public inheritance, however, you can control who knows that Dog is Animal and who knows inner workings of Animal. In case of protected or private inheritance only Dog will know that it is Animal, but it won't be obvious from the outside.
Composition:
In case of composition one class is included into another.
a Car is not a Wheel. But it contains Wheel. So operations that work on Wheel will not work on a Car.
By declaring member variable of type Wheel as public, private or protected you can control who can access Car's Wheels.
I believe that is clear enough?
Implementation details:
In case of C++, members of base class are included into derived class. Also methods that existed in base class will be accessible in derived class - somewhere. Access specifiers private, public and protected AND inheritance type determine which methods are visible and where.
I thought that there would be only one object
It is one object.
In microsoft compiler and g++ objects are "merged" together, meaning that in case of:
struct Base{
int a;
};
strict Derived: public Base{
int b;
};
Derived internally will probably (would need to check C++ standard to be sure) have this layout.
strict Derived{
int a;
int c;
};
or
struct Derived{
Base _;
int c;
};
In case of multiple inheritance and diamond inheritance things will get more complicated and base class can be included multiple times.
I found those two terms in the book of Meyers, but what is the difference?
Interface inheritance is public inheritance, while implementation inheritance is private inheritance.
If class B publicly inherits from A, B is an A: it inherits the whole interface of A, and a (reference/pointer to) a B object can be automatically be upcasted to A, and used wherever an object of A is expected. However, if B privately inherits from A, B is-implemented-in-terms-of A: only the implementation of A is inherited, not its interface. Thus (references/pointers to) B objects can not be used in places where A objects are expected.
Update
To reflect on #Michal's comment, here are some links (based largely on googling "c++ implementation inheritance") to demonstrate the common usage of these terms in the context of C++:
C++ Design/Coding tips - Part 7
Interfaces
Uses and Abuses of Inheritance, Part 1
Implementation (or class) inheritance is when you separate a common part of implementation in the base class.
Interface inheritance is when you use virtual methods. It is intended to separate interface from implementation and minimize dependencies between program elements.
The major difference is interface is public inheritance and implementation is private inheritance.
The data members and method of the public and protected section will be inherited from base class to derived class in their respective access specifier in public inheritance.At the same time the object of derived class can access the data members of base class as the normal method.
The data members and methods of public and protected section will be inherited from base class to derived class in private access specifier
Here's the difference between the two types of inheritance according to "Taligent's Guide to Designing Programs".
Inheritance
There are two forms of inheritance in C++: type inheritance and implementation inheritance. In both forms of inheritance, a derived class can share or override behavior inherited from a base class. However, use type inheritance only when it is necessary for a derived class to inherit type information as well. The primary reason to inherit type information is to allow for polymorphism.
Express type inheritance by deriving a class from a public base class; express implementation inheritance by deriving a class from a private or protected base class.
More at:
https://root.cern/TaligentDocs/TaligentOnline/DocumentRoot/1.0/Docs/books/WM/WM_23.html
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.