Inheritanced class uses inherited struct - c++

I have abstract base class and an empty struct that should be used inside this class
//base.hpp
class Base {
public:
virtual void do_something(const char* arr) {
h = reinterpret_cast<Header*>(arr); //What happens here in the derived class? I would want it to cast it to the respective derived struct
h->val = 10 //these are some common functionalities which I want to include in the base class
}
private:
Header *h;
}
//header.hpp
struct Header {
}
Both the class and struct are inherited
//derivedA.h
class DerivedA : public Base {
...
//this class should refer to HeaderA
}
//header.hpp
struct HeaderA : public Header{
int val;
bool is_it;
}
Similarly there's another derived class DerivedB and it's associated HeaderB.
How can I make the derived classes refer to its respective derived structs?
One of the reasons I have an empty base struct even though they have few common members is that I am using reinterpret_cast. The common members in the incoming buffer are arranged differently. But it is useful to define common functionalities in the base class. What am I missing here? How can I make this work?

0) using reinterpret_cast on a char* is a Really Bad Idea. Change your base constructor to take a Header pointer. Or don't since they don't share anything, there's no real reason to to use inheritance here.
Maybe you're leaving out a bunch of stuff in the base Header for clarity's sake, I dunno. But as written, you don't need the base header pointer in the first place.
1) Make HeaderA inherit from Header.
2) DerivedA's constructor takes a HeaderA* parameter, which is then passed to the base class's Header*-based constructor.
3) DerivedA keeps a separate copy of what it was passed in, with the correct type.
So something like
class Base {
public:
virtual ~Base() {} // virtual base destructor! Very important.
Base(Header* foo)
: header(foo) {
}
private:
Header* header;
...
};
// at the very least, you probably want a virtual destructor here too
struct Header {
virtual ~Header() {}
};
struct HeaderA : public Header {
...
};
class DerivedA : public Base {
public:
DerivedA(HeaderA* header) :
: Base(header)
, headerA(header)
{
...
}
private:
HeaderA* headerA;
};
Note that the ownership of HeaderA isn't addressed here At All. You might want to use a std::unique_ptr<Header> in the base class, and let RAII handle it for you everywhere else... rather than using references, like I have in the above code. Then at least there'd be some point to having it in the base class even if the header was completely empty.
Back to that cast from char* to Header*. I presume you're writing the header out with memcpy() or something like it either to a file, or a packet or some such, in an effort to be efficient.
Don't.
In both AAA MMORPG code bases I've worked on, each field of each struct was written out explicitly (to packets or files). It may have worked like an overly verbose memcpy() in some cases, but we made the effort, because the safety was Worth The Extra Effort. If you continue to do things the way you are, everything in your header has to be Right There.
no pointers
strings have to be fixed size arrays, arrays that will be mostly empty most of the time, because they're sized for your worst case scenario.
object pointers have to be replaced with object IDs, and that the object IDs have to be consistent between when they were written, and when they were read. And those IDs have to be stored in the struct, which means looking them up every time you have to use them.
You're locked into either "big endian" or "little endian" at write time, and heaven help you if your write "endian-ness" is different from your read "endian-ness". ("What the hell are big endian and little endian?" Google it. Right now. Seriously.)
By writing out fields individually you can do things like
write everything out in a particular endian-ness.
convert object pointers to object IDs.
write out a length and then the correct number of characters/bytes rather than a fixed/mostly-empty number of bytes.
encrypt field values (MMOs can't trust the data packets not to be sniffed so players can cheat)
change field order (it's fun to scramble your packets' field order and watch the hackers crash when they connect the first time, at which point you know which accounts to flag for Further Investigation. Yes, this is one of several reasons why your old version of some client won't work with the new version of the corresponding server.)

Related

C++ Upcasting from Multiple Inheritance; the source is not polymorphic

I am a newbiee in C++.
I have two pure abstract classes (like interfaces), and I derive a Class from these two pure abstracts classes.
In a case, I need to upcast the derived class pointer to one of the base abstract classes.
First of all, is there any limitation on that.
class IBase1
{
virtual ~IBase() = default;
}
class IBase2
{
virtual ~IBase2() = default;
}
class Derived : public IBase, public IBase2
{
}
Derived d;
IBase1* basePtr = dynamic_cast<IBase1*>(&d);
Herein, if I use any other cast, I am not pretty sure but I get invalid pointer from the cast, so I need to use dynamic_cast for upcasting from multiple inheritance, is that right?
When I do that, I get an error "source type is not polymorphic"
My base classes are pure abstract classes so they have at least one virtual methid so it should be ok, right but why I get this error? Is it about the multiple inheritance?
Edit: There are one more layer here.
My Derived Class needs to contain two different type of instances but my instances are really huge variable so as a C developer :), I was planning to use an Union for less memory usage.
The union has only instances of two classes which derived from pure abstract classes. So, I was assuming that the union instance address should also points the offsets of my class instances, but C++ cannot probably know the write member methods address.
class IFile
{
public:
virtual ~IFile() = default;
};
class IDirectory
{
public:
virtual ~IDirectory() = default;
};
class FileSystem1 : public IFile, public IDirectory
{
public:
FileSystem1() { }
virtual ~FileSystem1() final override = default;
private:
Native1APIInstance file;
};
class FileSystem2 : public IFile, public IDirectory
{
public:
FileSystem2() { }
virtual ~FileSystem2() final override = default;
private:
Native2APIInstance file;
};
union FileSystemInstance
{
FileSystem1 fs1;
FileSystem2 fs2;
FileSystemInstance(string path)
{
if (path[0] == '1') // initialise fs1
else if (path[0] == '2') // initialise fs2
}
};
FileSystem fs("<PATH to File System>");
IFile* file = reinterpret_cast<IFile*>(&fs);
Herein, I dont want to interest which instance is initialised. I want to work with only the base class interface. I am wondering is that somehow possible with an Union?
Thanks.
class FileSystem1 : public IFile, public IDirectory
Let's sit back and think about just that much for a moment. That asserts that a FileSystem1 is (or more formally, under any possible circumstances, can be used in place of) either an IFile or an IDirectory.
At least as most people use these terms, that's not how things are at all. As most people use the terms, a File system contains some things, each of which can be either a file or a directory:
class FS_node {
virtual std::string name() const { return name_; }
// ...
virtual ~FS_node = default;
};
class File : public FS_node {
// ...
};
class Directory : public FS_node {
// ...
};
class FileSystem {
std::vector<FS_node *> nodes;
public:
// ...
};
Now, from the sound of things, you have to deal with two entirely separate file systems. There are a number of ways of doing that. One possibility would be to have a base FileSystem class that defines an interface to a file system, then have two derivative classes that implement that interface in terms of two separate APIs at the OS level.
Another possibility would be to implement similar functionality, but instead of using inheritance, you'd specify the API interface class as a template parameter when you instantiate a FileSystem object:
template <class Api>
class FileSystem {
Api api;
public:
FileSystem(Api const &api) : api(api) {}
// FS functions for finding files and such go here,
// each implemented via the `Api` passed as a parameter
};
As to the difference between using templates and inheritance: it's pretty much the same as usual: templates are static, so if (for example) you want code that you can specify at compile time whether to compile for Windows or Linux, templates should work nicely. On the other hand, if you're dealing with something like a single collection of file systems, and that collection might contain a mixture of objects, each representing a different file system, and you want to be able to deal with all of them transparently at run time, then you'll probably need to use an inheritance hierarchy.
But at least to me, it seems fairly likely that your original design with FileSystem derived from both File and Directory classes is almost certainly a pretty serious mistake. We'd probably need to know a bit more about what you're doing to be sure of what approach is really optimal, but that's probably not it.
Ignoring all of that about the design for a moment, and looking at the question of how to convert from pointer to derived to point to base, we really have only two cases that matter a whole lot. If you used public inheritance (as shown in the question), the conversion doesn't require a cast at all:
FileSystem1 foo1;
IFile *fileBase = &foo1; // No problem.
IDirectory *dirBase = &foo1; // Likewise
If you used private derivation, then you've just found an exceptionally rare situation: one where you actually need to use a C-style cast to do the conversion properly:
class Base1 {};
class Base2 {};
// Note: private derivation:
class Derived : Base1, Base2 {};
Derived d;
Base1 *b1 = (Base1 *)&d;
Base2 *b2 = (Base2 *)&d;
For this specific case (converting a derived class to an inaccessible base class) none of the "new" C++ casts can do the job--you must us a C-style cast.
It seems the problem is about Union data structure.
For example, if I use union while the following works;
FileSystem fs;
fs.fs1.Func();
the below does not work
FileSystem fs;
FileSystem1* fs1 = &fs.fs1; (No casting, the same type)
fs1->Func();
I got an exception for the second case, it somehow cannot find the virtual function table (Access violation for vtable; 0xCCCCCCCC). Does not make sense to me.
If I change Union to Class type, the same code works. It must be about the Union itself. I need to study it well, or leave the idea. Thank you all.

Using/storing derived member in derived class with base class that stores base member

A situation I often come up against is having a set of classes, Base and Derived, where the Base class has ownership of a base-class member BaseMember, and the Derived class has a reference or pointer to the same object, but as a DerivedMember.
For example, a UI panel class that contains a specific instance of a certain type of control with some special-control functions, inheriting from a general class that contains a general control and has general-control functions.
First, say that BaseMember is inherited by DerivedMemeber.
Without using smart pointers, I might do something like this:
class Base
{
protected:
// receive ownership but only because we say so,
// someone else can still try to delete as it's "just a pointer"
Base(BaseMember* _bmember):
bmember(_bmember)
{}
public:
virtual ~Base()
{
// perform an owner's duty
delete bmember;
}
// functions that might be based on BaseMember + other base state
void SetMemberId(....)
{
bmember->SetId(baz);
}
private:
int baz;
BaseMember* bmember; //owned, but not smartly
}
class Derived: public Base
{
public:
Derived(DerivedMember* _dmember):
Base(_dmember),
dmember(_dmember)
{}
// functions that only make sense for Derived + Derived/Base state
void SetDerivedFrobulation()
{
// only a DerivedMember has frobulation, so only
// Derived allows users to access it
dmember->setFrobulation(foo);
}
private:
int foo; // some state
DerivedMember* dmember; // no ownership here
}
With smart pointers (C++11 and up, specifically, I don't really care about older C++ in this case), I am tempted to do something like this and never let the Base/DerivedMember object out into dumb-pointer-land where it could leak if there was an exception somewhere inconvenient.
class Base
{
protected:
// receive ownership
Base(std::unique_ptr<BaseMember> _member):
member(std::move(_member))
{}
virtual ~Base()
{}
public:
// public access functions here as before
private:
std::unique_ptr<BaseMember> member;
}
class Derived: public Base
{
public:
// pass the ownership down by unique_ptr
Derived(std::unique_ptr<DerivedMember> _dmember):
Base(std::move(_dmember)),
dmember(_dmember.get()) // _dmember is moved! SEGFAULT if access dmember later!
{}
// public access functions here as before
private:
// handy handle to the derived class so we don't need to downcast the base (or even access it!)
DerivedClass* dmember
}
As I noted there, you can't "steal a peek" at the DerivedMember class as it comes in to the Derived constructor, because the unique_ptr is moved away before Derived gets a look in.
I can see a solution in providing a protected access to the BaseMember and static_casting back to DerivedMember in the Derived constructor (i.e. after the Base constructor is done), but this seems an ugly way to get access back to a variable we let slip though our fingers!
Another way could be each inheritor of Base owns the pointer, and base just gets a dumb pointer. In this case, the Base destructor doesn't get access to the member, as it's already gone. Also it would duplicate the ownership logic needlessly.
I think either:
This is symptomatic of an anti-pattern and the design of the whole Base/Derived/BaseMember/DerivedMember system is not good practice.
I'm missing a trick and there is a clean way to do this without fumbling a smart pointer and making a leak possible or adding functions and exposing interfaces or casting too much.
Is this a good pattern for re-use, or should I look elsewhere?
Expanding on the use case (EDIT)
In a core library, I have a class DataInterpreter which shows "some interpretation" of data - could be a string, an image, etc. This is then inherited by, amongst others, TextInterpreter which presents a string.
I then have a DataDisplayPanel class which represents a piece of UI for displaying in an abstract sense. Exactly what is in this panel will depend on the interpreter used: a TextInterpreter should get a text entry field and say a button to set some text display option, and that is handled in TextDisplayPanel, which has "special" knowledge of the text aspect of the interpreter.
There is then a DataAggregatePanel which combines a number of DataDisplayPanels and provides some global settings that affect all displays (via virtual functions), and manages the panels in a std::vector<std::unique_ptr<DataDisplayPanel> >. This aggregate class doesn't deal with any of the derived classes at all, any functions would be polymorphic and defined in the base.
In the application (which depends on the core library), these classes are extended (by inheritance or composition, whichever makes more sense). For example, if the application is a WX GUI, I might have wxDataAggregatePanel which contains wxTextDisplayPanel (and others), all of which are wxPanels. In this case, wxTextDisplayPanel might own a wxTextEntry and either own or inherit TextInterpreter and use its knowledge of the TextInterpreter's specific methods to fill the text box with a string.
You may use delegating constructor:
class Derived: public Base
{
public:
Derived(std::unique_ptr<DerivedMember> _dmember):
Derived(_dmember, _dmember.get())
{}
// public access functions here as before
private:
Derived(std::unique_ptr<DerivedMember>& _dmember, DerivedMember* ptr):
Base(std::move(_dmember)),
dmember(ptr)
{}
private:
// handy handle to the derived class so we don't need to downcast the base (or even access it!)
DerivedClass* dmember
};

C++: Incorporating inheritance, polymorphism, and factories

I'm currently trying to make a pair of classes which depend on each other. Essentially, objects of class B create objects of class A. However, I am also using an inheritance hierarchy, so all derivatives of class B must also be able to create derivatives of class A (each derivative of B corresponds to a derivative of A, so DerB1 makes DerA1 objects, and DerB2 makes DerA2 objects).
I'm having problems with my implementation, and it may be silly, but I would like to see if anyone knows what to do. My code is below (I HATE reading other people's code, so I tried to make it as easy to read as possible...only a few important bits, which I commented to explain)
class BaseB {} // Declare BaseB early to use in BaseA constructor
class BaseA
{
public:
BaseA(BaseB* b) {}; // Declare the BaseA constructor (callable by all B classes, which pass a pointer to themselves to the constructor so the A objects can keep track of their parent)
}
class DerA:public BaseA
{
DerA(BaseB* b):BaseA(b) {}; // Inherit the BaseA constructor, and use initialization list
}
class BaseB
{
public:
virtual BaseA createA() = 0; // Virtual function, representing method to create A objects
}
class DerB:public BaseB
{
BaseA createA() {
DerA* a = new DerA(this); // Definition of createA to make a new A object, specifically one of type DerA (Error1: No instance of constructor "DerA::DerA" matches the argument list)
return a; // Error2: Cannot return DerA for BaseA function
}
}
So, I have two main problems, one is practical (Error1, as I seem to simply be calling the function wrong, even if I try to typecast this), one is philosophical (Error 2, as I don't know how to implement the features I want. If anyone could point out why Error1 is occurring, that would be wonderful! Error2, however, requires some explanation.
I would like my user (programmer) to interact with all A objects the same way. They will have the same exact public functions, but each will have VERY different implementations of these functions. Some will be using different data types (and so will require function contracts), but many will have the same data types just with different algorithms that they use on them. I would like some piece of code to work exactly the same way if one class A derivative is used or another is. However, in my current implementation, it seems that I need to return a DerA object instead of a BaseA object (at the site of Error2). This means that I will need to write a segment of main code SPECIFICALLY for a DerA object, instead of any arbitrary A object. I would like something like:
BaseB b = new DerB(); // Declare which derivative of BaseB I want to use
BaseA a = b->createA(b); // Call the createA function in that derivative, which will automatically make a corresponding A object
This way, I can simply choose which type of B object I would like in the first line (by my choice of B constructor, or tag, or template, or something), and the rest of the code will look the same for any type of object B (as each has the same public member functions, even though each object will perform those functions differently).
Would I be better off using templates or some other method instead of inheritance? (I apologize for being intentionally vague, but I hope my class A/B example should mostly explain what I need).
Thank you for any help. I apologize for asking two questions in one post and for being long-winded, but I am trying to learn the best way to approach a rather large redesign of some software.
You have several syntactical issues to get the errors solved:
Add the ; after each class definitions.
The first line should be a forward declaration: class BaseB /*{} NO!!*/ ;
Add public: to make constructor of DerA accessible for DerB
BaseA createA() should return a value, not a pointner (according to signature): return *a;
There is another potential hidden slicing issue, as createA() returns a value, an not a pointer. This means that your returned object (here *a), would be copied but as a real BaseA object. So only the BaseA part of the object will be copied, not the derived part. This could lead to some unexpected surprises.
In order to avoid slicing, consider returning a pointer, changing the signature of createA() accordingly. The object pointed to would then keep the right type without loosing anything.
If you would later need to copy the object, you could use a static cast if you are absolutely sure of the real type of the object pointed to:
BaseA *pba = pdb->createA(); // get pointer returned
DerA da = *static_cast<DerA*>(pba); // static cast with pointer
If you would need to copy pointed BaseA objects without necessarily knwowing for sure their real type, you could implement a virtual clone function in DerA (e.g. prototype design pattern)

Gradually construct an object

Suppose there is a hierarchy of two classes (class Derived: public Base). Both these classes have big memory footprint and costly constructors. Note that nothing in these classes is allocated in heap: they just have a big sizeof.
Then there is a function with a fast path (executed always) and a slow path (executed conditionally). Fast path needs a Base instance, and slow path needs a Derived instance constructed from existing base. Also, slow path decision can be made only after the fast path.
Current code looks like this:
void f()
{
Base base;
/* fast path */
if (need_slow_path) {
Derived derived (base);
/* slow path */
}
}
This is inefficient, because the base needs to be copied into derived; also the base is allocated twice and there is a risk of overflowing the stack. What I want to have:
allocate memory for Derived instance
call Base ctor on it
execute the fast path
if needed, call Derived ctor on the existing Base instance and execute the slow path
Is it possible in C++? If not, what are possible workarounds? Obviously, I'm trying to optimize for speed.
I am afraid this is not possible just as you wrote - any constructor of Derived must call a constructor of the Base subobject, so the only way to do that legally would be to call Base's destructor first, and I believe you don't want that.
However, it should be easy to solve this with a slight redesign - prefer composition over inheritance, and make Derived a separate class that will store a reference (in the general sense; it can of course be a pointer) to Base and use it. If access control is an issue, I feel a friend is justified here.
You should change your design slightly to change your reliance on inheritance to that on composition.
You could encapsulate members of derived class (not present in the base class) into another class, and keep it's null reference in the derived class.
Now directly initialize derived class without initializing new class's object.
Whenever slow path is required, you can initialize and use it.
Benefits
Inheritance relationship between derived and base class is preserved.
Base class object is never copied.
You have lazy initialization of derived class.
I can fake it.
Move/all the data of derived into an optional (be it boost or std::ts::optional proposal for post C++14, or hand rolled).
Iff you want the slow path, initialize the optional. Otherwise, leave it as nullopt.
There will be a bool overhead, and checks when you assign/compare/destroy implicit. And things like virtual functions will be derived (ie, you have to manage dynamic dispath manually).
struct Base {
char random_data[1000];
// virtual ~Base() {} // maybe, if you intend to pass it around
};
struct Derived:Base {
struct Derived_Data {
std::string non_trivial[1000];
};
boost::optional< Derived_Data > m_;
};
now we can create a Derived, and only after we m_.emplace() does the Derived_Data get constructed. Everything still lives is in one contiguous memory block (with a bool injected by the optional to track if m_ was constructed).
Not sure if you can do exacactly what you want i.e execute "fast" path before second contructor but i think you use 'placement new' feature - manually call contructors based on need_slow_path predicate. i.e but that changes flow a little:
allocate memory for Derived instance
call Base or Derived ctor on it
execute the fast path
execute the slow path (if needed(
The example code
#include <memory>
void f(bool need_slow_path)
{
char bufx[sizeof(Derived)];
char* buf = bufx;
Derived* derived = 0;
Base* base = 0;
if (need_slow_path ) {
derived = new(buf) Derived();
base = derived;
} else {
base = new(buf) Base();
}
/* fast path using *base */
if (need_slow_path) {
/* slow path using *base & * derived */
}
// manually destroy
if (need_slow_path ) {
derived->~Derived();
} else {
base->~Base();
}
}
Placement new is well described here: What uses are there for "placement new"?
Can you define move copy con't in your compiler ?
There is an excellent explanation (although a bit long ) here
https://skillsmatter.com/skillscasts/2188-move-semanticsperfect-forwarding-and-rvalue-references
I don't have experience with move semantics so I might be wrong but since you want to avoid coping the base object when passing it to the derived class move semantics should do the trick
First extract constructor code into initializing methods both for Base and Derived.
Then I would make the code similar to this:
void f()
{
Derived derived;
derived.baseInit();
/* fast path */
if (need_slow_path) {
derived.derivedInit();
/* slow path */
}
}
It's a good idea to extract classes and use composition as Tanmay Patil suggested in his answer.
And yet another hint: If you haven't done already, dive into Unit-Tests. They will help you dealing with huge classes.
Perhaps instead of a class and constructors, you need a plain-old-struct and initialization functions here. You’ll be giving up a lot of the C++ conveniences, of course, but you’ll be able to implement your optimization.

When do programmers use Empty Base Optimization (EBO)

I was reading about Empty Base Optimization(EBO). While reading, the following questions popped up in my mind:
What is the point of using Empty class as base class when it contributes nothing to the derived classes (neither functionality-wise, nor data-wise)?
In this article, I read this:
//S is empty
class struct T : S
{
      int x;
};
[...]
Notice that we didn’t lose any data or
code accuracy: when you create a
standalone object of type S, the
object’s size is still 1 (or more) as
before; only when S is used as base
class of another class does its memory
footprint shrink to zero. To realize
the impact of this saving, imagine a
vector that contains 125,000
objects. The EBO alone saves half a
megabyte of memory!
Does it mean that if we don't use "S" as base class of "T", we would necessarily consume double of megabyte of memory? I think, the article compares two different scenarios which I don't think is correct.
I would like to know a real scenario when EBO can proven to be useful.(means, in the same scenario, we would necessarily be at loss IF we don't use EBO!).
Please note that if your answer contains explanations like this :
The whole point is that an empty class has non-zero size, but when derived or deriving it can have zero size, then I'm NOT asking that, as I know that already. My question is, why would anyone derive his class from an empty class in the first place? Even if he doesn't derive and simply writes his class (without any empty base), is he at loss in ANY way?
EBO is important in the context of policy based design, where you generally inherit privately from multiple policy classes. If we take the example of a thread safety policy, one could imagine the pseudo-code :
class MTSafePolicy
{
public:
void lock() { mutex_.lock(); }
void unlock() { mutex_.unlock(); }
private:
Mutex mutex_;
};
class MTUnsafePolicy
{
public:
void lock() { /* no-op */ }
void unlock() { /* no-op */ }
};
Given a policy based-design class such as :
template<class ThreadSafetyPolicy>
class Test : ThreadSafetyPolicy
{
/* ... */
};
Using the class with a MTUnsafePolicy simply add no size overhead the class Test : it's a perfect example of don't pay for what you don't use.
EBO isn't really an optimization (at least not one that you do in the code). The whole point is that an empty class has non-zero size, but when derived or deriving it can have zero size.
This is the most usual result:
class A { };
class B { };
class C { };
class D : C { };
#include <iostream>
using namespace std;
int main()
{
cout << "sizeof(A) + sizeof(B) == " << sizeof(A)+sizeof(B) << endl;
cout << "sizeof(D) == " << sizeof(D) << endl;
return 0;
}
Output:
sizeof(A) + sizeof(B) == 2
sizeof(D) == 1
To the edit:
The optimization is, that if you actually do derive (for example from a functor, or from a class that has only static members), the size of your class (that is deriving) won't increase by 1 (or more likely 4 or 8 due to padding bytes).
The "Optimization" in the EBO means the case when you use base class can be optimized to use less memory than if you use a member of the same type. I.e. you compare
struct T : S
{
int x;
};
with
struct T
{
S s;
int x;
};
not with
struct T
{
int x;
};
If your question is why would you have an empty class at all (either as a member, or as a base), it is because you use its member functions. Empty means it has no data member, not that it does not have any members at all. Things like this are often done when programming with templates, where the base class is sometimes "empty" (no data members) and sometimes not.
Its used when programmers want to expose some data to client without increasing the client class size. The empty class can contain enums and typedefs or some defines which the client can use.The most judicious way to use such a class it it to,inherit such a class privately. This will hide the data from outside and wil not increase your class size.
There can be empty classes which do not have any member variables, but member functions (static or non static) which can act as utility classes, lets call this EmptyClass. Now we can have a case where we want to create a class (let's call it SomeClass) which have a containment kind of relation with EmptyClass, but not 'is-a' relation. One way is to create a member object of type EmptyClass in SomeClass as follows:
class EmptyClass
{
public:
void someFun1();
static int someUtilityFun2();
};
//sizeof(EmptyClass) = 1
class SomeClass
{
private:
EmptyClass e;
int x;
};
//sizeof(SomeClass) = 8
Now due to some alignment requirements compilers may add padding to SomeClass and its size is now 8 bytes. The better solution is to have a SomeClass derive privately from EmptyClass and in this way SomeClass will have access to all member functions of EmptyClass and won't increase the extra size by padding.
class SomeClass : private EmptyClass
{
private:
int x;
}
//sizeof(SomeClass) = 4
Most of the time, an empty base class is either used polymorphically (which the article mentions), as "tag" classes, or as exception classes (although those are usually derived from std::exception, which is not empty). Sometimes there is a good reason to develop a class hierarchy which begins with an empty base class.
Boost.CompressedPair uses the EBO to shrink the size of objects in the event that one of the elements is empty.
EASTL has a good explanation as to why they needed EBO, its also explained in-depth in the paper they link to/credit
EBO is not something the programmer influences, and/or the programmer would be punished for if (s)he chose not to derive from an empty base class.
The compiler controls whether for:
class X : emptyBase { int X; };
class Y { int x };
you get sizeof(X) == sizeof(Y) or not. If you do, the compiler implements EBO, if not, it doesn't.
There never is any situation where sizeof(Y) > sizeof(X) would occur.
The primary benefit I can think of is dynamic_cast. You can take a pointer to S and attempt to dynamic_cast it to anything that inherits from S- assuming that S offers a virtual function like a virtual destructor, which it pretty much must do as a base class. If you were, say, implementing a dynamically typed language, you may well wish or need for every type to derive from a base class purely for the purposes of type-erased storage, and type checking through dynamic_cast.