Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here:
Cookie Policy

Derived class issues with arrays and casting in C++

I’m working my way through C++ FAQs book by Cline and Lomow, and it’s excellent. There’s lots of issues going on with inheritance, arrays and casting that could be a real pain to deal with towards the end of system development, but that you can nip in the bud and make life easier for yourself. For example, just knowing that an array of objects of a Derived class is NOT a kind-of array of objects of the Base class can prevent you a lot of headaches…

// Book: C++ FAQs by Cline & Lomow// FAQ 136 & 137 - Is array-of Derived a kind-of array-of Base?// Answer: NO!#include <iostream>usingnamespace std;class Base
{protected:int i;public:
Base(): i(42*42){}virtual ~Base(){}virtualvoid service(){cout<<"Base::service() called.\n"<< flush;}};class Derived :public Base
{protected:// Add some extra things so that an object of type Derived is a different// size to an object of type Baseint j;float k;unsignedlong l;public:
Derived(): Base(), j(42*42*42){}virtualvoid service(){cout<<"Derived::service() called.\n"<< flush;}};// Userland functionvoid useSubscript(Base *b){cout<<"b[0].service(): "<< flush; b[0].service();cout<<"b[1].service(): "<< flush; b[1].service();// BOOM! Segfault!// This fails because the size of Base and the size of Derived are different:// "The fundamental problem is that a pointer to the first of an array-of-things// has exactly the same type as a pointer to a single thing. This was inherited// from C."//// In essence, as we're passing in Base pointers, in this case Base moves from// element to element in 16 byte intervals, but we actually provided an array// of Derived objects, which have a size of 32 bytes each, so b[1] starts// at b[0]+16, which is really only half-way through our first Derived element d[0]!//// The way to do this properly is to use a templatised container class instead.// If you tried to pass Array<Derived> as Array<Base> this would be caught at compile time.}int main(){
Derived d[10];cout<<"Base has a size of : "<<sizeof(Base)<<" bytes."<< endl;// 16 bytescout<<"Derived has a size of: "<<sizeof(Derived)<<" bytes."<< endl << endl;// 32 bytes
useSubscript(d);return0;}