简体   繁体   中英

Base pointer consistence in a non-virtual single inheritance class hierarchy

Is it safe to assume that in a non-virtual single-inheritance class hierarchy (with or without templates involved) the base class pointer of children and parent classes are the same? And the first member of the root class is also always at the same location (first implies second, but this is my main concern) .

struct parent {
    int type_ = 0;
    parent(int type):type_(type) {}
};

struct child: parent {
    child():parent(1) {}
};

child ch;
printf("parent %p\r\n", &static_cast<parent&>(ch).type_);
printf("child %p\r\n", &static_cast<child&>(ch).type_); // :)

From my C++-fu, common sense and tests it should be but I'm looking for a C++ standard compliant answer to comfort me. :)

PS : See the code on ideone .com .

Both of your classes are example of "standard-layout class" . It is mandated by Standard that such class must be compatible with C -style memory layout. That means, pointer to a class object is always the same as pointer to the first data-member of the class. So, yes, it is mandated by the Standard. (I'm now trying to find the reference to "standard-layout class" ).

EDIT : (Definition taken from this question , I don't have Standard at hand, sorry)

A standard-layout class is a class that:

  • has no non-static data members of type non-standard-layout class (or array of such types) or reference, has no virtual functions (10.3) and no virtual base classes (10.1),
  • has the same access control (Clause 11) for all non-static data members,
  • has no non-standard-layout base classes,
  • either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and
  • has no base classes of the same type as the first non-static data member.

You can always cast derived class to base class.

class Base{
public:
  int n;
};

class Derived: public base{

};


//you can do this:
Derived obj;
Base *p = &obj;//just take the derived address and put in base pointer, without cast.
cout<<p->n;

It means the members of the base are always located in the beginning of the derived, and in the same order.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM