C++ Memory layout of inheritance - c++

If I have two classes, one inheriting from the other, and the child class only containing functions, will the memory layout be the same for both classes?
e.g.
class Base {
int a,b,c;
};
class Derived: public Base {
// only functions.
};
I've read that the compiler can not reorder data members, and I do not require multiple-inheritance on the Derived class. Is there any situation where the memory layout will not be the same? (Multiple inheritance may be needed for the Base class)

Both Base and Derived here are standard layout classes. Since standard layout is intended to for interoperation with other languages (most notably C), yes, you can expect the layout to be the same for both. If you add multiple-inheritance to the mix however, the result may or may not be a standard layout class. You can check the rules for that in the post linked above.

The layout must be the same, because you can access derived instances through pointers to the base class.
Which means they would still be the same even if you had added data members.
Which also means it would've been the same even if you had used multiple inheritance.
(Although in that case, you might need to specifically do static_casts to specify which instance of the base you're referring to, since the derived class pointer need not be the same as the base class pointer.)

It varies compiler to compiler, but I would think for the most common compilers your assumption would be correct. g++/gcc for certain work as you suggest, I'm not sure about other though.

As they are, the layout of both classes is the same, but note that if you add any virtual function to the derived type, then the layout will change (or at least can change).
Now, from the description it seems that what you are trying to do is to create a type to provide member functions on top of an existing class, if that is the case, you should probably consider other different designs, like using free functions (C style).

DON'T count on it.
But the memory layout might in fact be the same for some common compilers.

Related

Example for non-virtual multiple inheritance

Is there a real-world example where non-virtual multiple inheritance is being used? I'd like to have one mostly for didactic reasons. Slapping around classes named A, B, C, and D, where B and C inherit from A and D inherits from B and C is perfectly fine for explaining the question "Does/Should a D object have one or two A sub-objects?", but bears no weight about why we even have both options. Many examples care about why we do want virtual inheritance, but why would we not want virtual inheritance?
I know what virtual base classes are and how to express that stuff in code. I know about diamond inheritance and examples of multiple inheritance with a virtual base class are abundant.
The best I could find is vehicles. The base class is Vehicle which is inherited by Car and Boat. Among other things, a Vehicle has occupants() and a max_speed(). So an Amphibian that inherits from both Car and Boat inherits different max_speed() on land and water – and that makes sense –, but also different occupants() – and that does not make sense. So the Vehicle sub-objects aren't really independent; that is another problem which might be interesting to solve, but this is not the question.
Is there an example, that makes sense as a real-world model, where the two sub-objects are really independent?
You're thinking like an OOP programmer, trying to design abstract models of things. C++ multiple inheritance, like many things in C++, is a tool that has a particular effect. Whether it maps onto some OOP model is irrelevant next to the utility of the tool itself. To put it another way, you don't need a "real-world model" to justify non-virtual inheritance; you just need a real-world use case.
Because a derived class inherits the members of a base class, inheritance often is used in C++ as a means of collecting a set of common functionality together, sometimes with minimal interaction from the derived class, and injecting this functionality directly into the derived class.
The Curiously Recurring Template Pattern and other mixin-like constructs are mechanisms for doing this. The idea is that you have a base class that is a template, and its template parameter is the derived class that uses it. This allows the base class to have some access to the derived class itself without virtual functions.
The simplest example I can think of in C++ is enable_shared_from_this, which allows an object whose lifetime is currently managed by a shared_ptr to actually retrieve a shared_ptr to that object just from a pointer/reference to that object. That uses CRTP to add the various members and interfaces needed to make shared_from_this possible to the derived class. And since the inheritance is public, it also allows shared_ptr's various functions that "enable shared_from_this" to to detect that a particular type has the shared_from_this stuff in it and to properly initialize it.
enable_shared_from_this doesn't need virtual inheritance, and indeed would probably not work very well with it.
Now imagine that I have some other CRTP class that injects some other functionality into an object. This functionality has nothing to do with shared_ptr, but it uses CRTP and inheritance.
Well, if I now write some type that wants to inherit from both enable_shared_from_this and this other functionality, well, that works just fine. There is no need for virtual inheritance, and in fact doing so would only make composition that much harder.
Virtual inheritance is not free. It fundamentally changes a bunch of things about how a type relates to its base classes. If you inherit from such a type, your constructors have to initialize any virtual base classes directly. The layout of such a type is very odd and is highly unlikely to be standardized. And various other things. C++ tries not to make programmers pay for functionality they don't use, so if you don't need the special properties of virtual inheritance, you shouldn't be using it.
Its the same reason C++ has non-virtual methods -- because the implementation is simpler and more efficient if you use non-virtual inheritance, so you need to explicitly ask for virtual inheritance if you want it. Since you don't need it if your classes never use multiple inheritance, that is the default.

Should I use base classes or child classes to access enum values/constants defined in base classes?

Let's say we have two classes, Base and Child. Child inherits Base. Value is a constant variable (or a enum value) defined in Base, so it can be accessed by Base::Value.
Now we are dealing with some variables of type Child. I notice that in many documents and sample codes, people tend to use Base::Value instead of Child::Value though they are dealing with Child instances. For example, in Qt library there are QIODevice and QBuffer (the later is a child of the former), and QBuffer has a method open. The documents tend to use something like buffer.open(QIODevice::ReadWrite, ...); instead of buffer.open(QBuffer::ReadWrite, ...);. There are many other examples I believe you all have seen frequently.
I'm a bit curious why people tend to use the base classes to access those values, since sometimes we don't know for sure in which classes is the value defined, and more importantly, it is possible that the child classes may override the values defined in base classes. So isn't it the best to access constant values through the current class (WhateverClassBeingUsed::Value)?
I'm a bit curious why people tend to use the base classes to access
those variables, since sometimes we don't know for sure in which
classes is the value defined, and more importantly, it is possible
that the child classes may override the values defined in base
classes.
Sure, but both of these scenarios are hideously bad code and you want to avoid them. You cannot override the value of an enum, you could only define a coincidentally-named enum. It would be a totally different type and it would not compile.
Not knowing for sure in which class it's defined is only useful for implementation details... the user has to know which class to use, so they find out and then they use it.
There's no genuine loss by using the class in which the enum is defined.

Does the C++ spec allow an instance of a non-virtual class to include memory for a vtable pointer?

Does the C++ spec allow an instance of a non-virtual class to include memory for a vtable pointer? I am asking this, because a colleague said he once used a C++ compiler where the following happened:
class MyClass
{
public:
HeaderStruct header; //This had extra words
BodyStruct message_body;
};
He then changed the code to this, which got rid of the extra words:
struct MyClass
{
HeaderStruct header; //This did not have extra words
BodyStruct message_body;
};
None of these types was virtual or derived from anything virtual. So the theory was that perhaps this particular compiler allocated memory for a vptr for the class instances but not for the struct instances. So I'm just trying to determine if such compiler behavior is precluded by the spec.
Thanks!
Ken
By standard 'struct' and 'class' are synonyms that affect only default access to bases and members in class definition.
Standard defines POD (plain old data). POD may not have user defined constructors, destructors, assignment operators, non-static reference members and anything virtual (also non-static members of it should not have such things). PODs have strict memory layout rules (for compatibility with C) and so the implementation can not add there any vtables or RTTI information or the like.
However the C++ compilers of old times did often deviate from standard and from each other quite a bit so your colleague might be right too.
I'm unable to find an online reference for it with a quick search, but I'm pretty sure a compiler is permitted to do ANYTHING with the layout of any class; in particular, in classes without any virtual methods, it's allowed to put a vftp or not, depending on how it's feeling that day, whether it's declared as class or struct (which are equivalent in C++ except for the default access specifier), the phase of the moon, or anything else. The only restriction that I'm aware of is that the top part of a derived object shall match the layout of its first (non-virtual) base class. And I'm not even sure it has to be the first one.
You should not at any time depend on a particular compiler's decision on the layout of an object. Many compilers put a vftp in all objects without exception, in order to provide run-time type information to debuggers, or just to make their own lives easier. Some don't. You have no reasonable way of knowing, except through the sizeof operator.
There's no such thing as a "virtual class". You might mean virtual inheritance, which involves using the virtual keyword before a class name, but the virtual-ness applies to the inheritance relationship, not the class itself. Or maybe you just mean a class that contains virtual functions.
At any rate, the C++ spec doesn't say anything about virtual tables at all; those are specific to an implementation. Typically a virtual table will only be added if the class contains virtual functions, has virtual bases, or inherits from other classes that do. But it would be perfectly valid for an implementation to put a virtual table in every instance of every class.
The virtual modifier for a class is only used if/when you might inherit from the class more than once. In the I/O streams library, istream and ostream both inherit from ios_base, and iostream inherits both istream and ostream. The virtual modifier allows you to inherit twice without getting two copies of the base class members.
But any method can be virtual, even in a non-virtual class -- and therefore any class can have a vtable.
But the real answer to your question :) is that a class and struct are almost identical, except that in a class, members are private by default, whereas in a struct they're public by default.

If a class might be inherited, should every function be virtual?

In C++, a coder doesn't know whether other coders will inherit his class. Should he make every function in that class virtual? Are there any drawbacks? Or is it just not acceptable at all?
In C++, you should only make a class inheritable from if you intend for it to be used polymorphically. The way that you treat polymorphic objects in C++ is very different from how you treat other objects. You don't tend to put polymorphic classes on the stack, or pass them by or return them from functions by value, since this can lead to slicing. Polymorphic objects tend to be heap-allocated, be passed around and returns by pointer or by reference, etc.
If you design a class to not be inherited from and then inherit from it, you cause all sorts of problems. If the destructor isn't marked virtual, you can't delete the object through a base class pointer without causing undefined behavior. Without the member functions marked virtual, they can't be overridden in a derived class.
As a general rule in C++, when you design the class, determine whether you want it be inherited from. If you do, mark the appropriate functions virtual and give it a virtual destructor. You might also disable the copy assignment operator to avoid slicing. Similarly, if you want the class not to be inheritable, don't give it any of these functions. In most cases it's a logic error to inherit from a class that wasn't designed to be inherited from, and most of the times you'd want to do this you can often use composition instead of inheritance to achieve this effect.
No, not usually.
A non-virtual function enforces class-invariant behavior. A virtual function doesn't. As such, the person writing the base class should think about whether the behavior of a particular function is/should be class invariant or not.
While it's possible for a design to allow all behaviors to vary in derived classes, it's fairly unusual. It's usually a pretty good clue that the person who wrote the class either didn't think much about its design, lacked the resolve to make a decision.
In C++ you design your class to be used either as a value type or a polymorphic type. See, for example, C++ FAQ.
If you are making a class to be used by other people, you should put a lot of thought into your interface and try to work out how your class will be used. Then make the decisions like which functions should be virtual.
Or better yet write a test case for your class, using it how you expect it to be used, and then make the interface work for that. You might be surprised what you find out doing it. Things you thought were absolutely necessary might turn out to be rarely needed and things that you thought were not going to be used might turn out to be the most useful methods. Doing it this way around will save you time not doing unnecessary work in the long run and end up with solid designs.
Jerry Coffin and Dominic McDonnell have already covered the most important points.
I'll just add an observation, that in the time of MFC (middle 1990s) I was very annoyed with the lack of ways hook into things. For example, the documentation suggested copying MFC's source code for printing and modifying, instead of overriding behavior. Because nothing was virtual there.
There are of course a zillion+1 ways to provide "hooks", but virtual methods are one easy way. They're needed in badly designed classes, so that the client code can fix things, but in those badly designed classes the methods are not virtual. For classes with better design there is not so much need to override behavior, and so for those classes making methods virtual by default (and non-virtual only as active choice) can be counter-productive; as Jerry remarked, virtuals provide opportunites for derived classes to screw up.
There are design patterns that can be employed to minimize the possibilities of screw-ups.
For example, wrapping internal virtuals in exposed non-virtual methods with sanity checks, and, for example, using decoupled event handling (where appropriate) instead of virtuals.
Cheers & hth.,
When you create a class, and you want that class to be used polymorphically you have to consider that the class has two different interfaces. The user interface is defined by the set of public functions that are available in your base class, and that should pretty much cover all operations that users want to perform on objects of your class. This interface is defined by the access qualifiers, and in particular the public qualifier.
There is a second interface, that defines how your class is to be extended. At that level you have to think on what behavior you want to be overridden by extending classes, and what elements of your object you want to provide to extending classes. You offer access to derived classes by means of the protected qualifier, and you offer extension points by means of virtual functions.
You should try to follow the Non-Virtual Interface idiom whenever possible. That idiom (google for it) basically tries to fully separate the two interfaces by not having public virtual functions. Users call non-virtual functions, and those in turn call on configurable functionalities by means of protected/private virtual functions. This clearly separates extension points from the class interface.
There is a single case, where virtual has to be part of the user interface: the destructor. If you want to offer your users the ability to destroy derived objects through pointers to the base, then you have to provide a virtual destructor. Else you just provide a protected non-virtual one.
He should code the functions as it is, he shouldn't make them virtual at all, as in the circumstances specified by you.
The reasons being
1> The CLASS CODER would obviously have certain use of functions he is using.
2> The inherited class may or may not make use of these functions as per requirement.
3> Any function may be overwritten in derived class without any errors.

Structure of a C++ Object in Memory Vs a Struct

If I have a class as follows
class Example_Class
{
private:
int x;
int y;
public:
Example_Class()
{
x = 8;
y = 9;
}
~Example_Class()
{ }
};
And a struct as follows
struct
{
int x;
int y;
} example_struct;
Is the structure in memory of the example_struct simmilar to that in Example_Class
for example if I do the following
struct example_struct foo_struct;
Example_Class foo_class = Example_Class();
memcpy(&foo_struct, &foo_class, sizeof(foo_struct));
will foo_struct.x = 8 and foo_struct.y = 9 (ie: the same values as the x,y values in the foo_class) ?
The reason I ask is I have a C++ library (don't want to change it) that is sharing an object with C code and I want to use a struct to represent the object coming from the C++ library. I'm only interested in the attributes of the object.
I know the ideal situation would be to have Example_class wrap arround a common structure between the C and C++ code but it is not going to be easy to change the C++ library in use.
The C++ standard guarantees that memory layouts of a C struct and a C++ class (or struct -- same thing) will be identical, provided that the C++ class/struct fits the criteria of being POD ("Plain Old Data"). So what does POD mean?
A class or struct is POD if:
All data members are public and themselves POD or fundamental types (but not reference or pointer-to-member types), or arrays of such
It has no user-defined constructors, assignment operators or destructors
It has no virtual functions
It has no base classes
About the only "C++-isms" allowed are non-virtual member functions, static members and member functions.
Since your class has both a constructor and a destructor, it is formally speaking not of POD type, so the guarantee does not hold. (Although, as others have mentioned, in practice the two layouts are likely to be identical on any compiler that you try, so long as there are no virtual functions).
See section [26.7] of the C++ FAQ Lite for more details.
Is the structure in memory of the example_struct simmilar to that in Example_Class
The behaviour isn't guaranteed, and is compiler-dependent.
Having said that, the answer is "yes, on my machine", provided that the Example_Class contains no virtual method (and doesn't inherit from a base class).
In the case you describe, the answer is "probably yes". However, if the class has any virtual functions (including virtual destructor, which could be inherited from a base class), or uses multiple inheritance then the class layout may be different.
To add to what other people have said (eg: compiler-specific, will likely work as long as you don't have virtual functions):
I would highly suggest a static assert (compile-time check) that the sizeof(Example_class) == sizeof(example_struct) if you are doing this. See BOOST_STATIC_ASSERT, or the equivalent compiler-specific or custom construction. This is a good first-line of defense if someone (or something, such as a compiler change) modifies the class to invalidate the match. If you want extra checking, you can also runtime check that the offsets to the members are the same, which (together with the static size assert) will guarantee correctness.
In the early days of C++ compilers there were examples when compiler first changes struct keywords with class and then compiles. So much about similarities.
Differences come from class inheritance and, especially, virtual functions. If class contains virtual functions, then it must have a pointer to type descriptor at the beginning of its layout. Also, if class B inherits from class A, then class A's layout comes first, followed by class B's own layout.
So the precise answer to your question about just casting a class instance to a structure instance is: depends on class contents. For particular class which has methods (constructor and non-virtual destructor), the layout is probably going to be the same. Should the destructor be declared virtual, the layout would definitely become different between structure and class.
Here is an article which shows that there is not much needed to do to step from C structures to C++ classes: Lesson 1 - From Structure to Class
And here is the article which explains how virtual functions table is introduced to classes that have virtual functions: Lesson 4 - Polymorphism
Classes & structs in C++ are the equivalent, except that all members of a struct are public by default (class members are private by default). This ensures that compiling legacy C code in a C++ compiler will work as expected.
There is nothing stopping you from using all the fancy C++ features in a struct:
struct ReallyAClass
{
ReallyAClass();
virtual !ReallAClass();
/// etc etc etc
};
Why not explicitly assign the class's members to the struct's when you want to pass the data to C? That way you know your code will work anywhere.
You probably just derive the class from the struct, either publicly or privately. Then casting it would resolve correctly in the C++ code.