CMP EMBEDDED.COM

Login | Register     Welcome Guest  
HOME DESIGN PRODUCTS COLUMNS E-LEARNING CONFERENCES CODE FORUMS/BLOGS NEWSLETTERS CONTACT FEATURES RSS RSS

Classes are structures, and then some
A C++ class is a C structure, but with added features. Only some of those features alter the layout of class objects.



Embedded.com

Non-virtual member functions don't occupy data storage either. (They do occupy code space.) Static data members do occupy data storage, but not in the objects of which they are members. Thus, adding either non-virtual member functions or static data members to a class doesn't alter the storage layout for objects of that class. For example, objects of a widget class defined as:

class widget
{
public:
    widget();           // constructor
    ~widget();          // destructor
    char m1;
    int m2;
    char m3;
    static int k;       // static data member
};

have the same storage layout with or without these new members (the ones highlighted).

On the other hand, adding one or more virtual functions to a class that previously had none, as in:


class widget
{
public:
    widget();
    virtual ~widget();  // virtual destructor
    char m1;
    int m2;
    char m3;
    static int k;};

typically adds a hidden non-static data member of pointer type, called a vptr, thus increasing sizeof(widget) by the size of that pointer. The presence of the vptr has no impact on the size and alignment of any of the other data members, and typically no impact on the padding in the class.

Adding a base class to a class that previously had none, as in:


class widget: public gadget
{
public:
    widget();
    virtual ~widget();  // virtual destructor
    char m1;
    int m2;
    char m3;
    static int k;
};

effectively adds a hidden non-static data member of the base class type, called the base class sub-object, thus increasing sizeof(widget) by the size of a gadget plus any additional padding that may be needed.

The C++ Standard says nothing about the placement of the base class sub-object and the vptr. Many compilers place the vptr at the beginning, followed by the base class sub-object and then the non-static data members. For example, the compiler might lay out the storage for objects of the derived widget class (just above) as if widget had been defined as:


class widget
{
public:
    widget_vtable *vptr;
    gadget base_class_subobject;
    char m1;
    int m2;
    char m3;
};

Others place the base class sub-object before the vptr.

The compiler may insert padding as needed. If the gadget base class already has its own vptr, widget objects can use that vptr as their own, and the compiler can omit the allocation of a separate vptr in the widget itself.

The classes in all of my examples thus far have only public members. C++ has additional rules governing the placement of members with different accessibility. I'll discuss those rules next month.

Dan Saks is president of Saks & Associates, a C/C++ training and consulting company. For more information about Dan Saks, visit his website at www.dansaks.com. Dan also welcomes your feedback: e-mail him at dan@dansaks.com. For more information about Dan click here .

Endnotes:
1. Saks, Dan, "Padding and rearranging structure members," Embedded Systems Design, May 2009, p. 11.

2. ISO/IEC Standard 14882:2003(E), Programming languages--C++.

1 | 2

Rate this article: Low High
Current rating
  • .
Embedded.com Career Center
Looking for a new job?
SEARCH JOBS

Browse all jobs

SPONSOR
RECENT JOB POSTINGS



TECH PAPER
WEBINAR
WEBINAR
WEBINAR




 :