0

How is an array that stores multiple IClass objects, into which we add instances of Class objects that implements IClass gets stored in memory? I am trying to confirm if my assumption is right (in case of 32 bit app) we have an array of 32 bit pointers to the IClass objects that have a 32 bit pointer to the actual instance object of Class that takes up sizeof(Class) in memory? Also, if an interface doesnt have any virtual/abstract methods it only has a 32 bit pointer at its root and thats it?

Is this right? as always, any input appreciated

edit:

say we have the following definitons:

class Class : IClass
{
   int foo();
   int bar;
}

class IClass
{
   virtual int vfunc();
}

// array def:
IClass arr[1337];

I begin storing Class in the array arr, how does the runtime store sizeof(Class) into something that have sizeof(IClass) allocated for it?

geo10
  • 366
  • 2
  • 11
  • 2
    The `IClass` object is a subobject of the derived object. It doesn't necessarily have a pointer to the subobject; if there are virtual methods, it will have a pointer to a vtable which has pointers to the real implementation of each virtual method in the most-derived object. – cdhowie Jul 25 '20 at 14:11
  • cheers for comment. so the array will point to an object of sizeof(Class)? – geo10 Jul 25 '20 at 14:17
  • An interface only base class, or abstract base class, with no virtual methods isn't much of an interface or abstraction. – Eljay Jul 25 '20 at 14:44
  • I'm pretty sure that is *implementation defined*. – Jesper Juhl Jul 25 '20 at 15:03
  • 1
    @geo10 The pointer will be to a subobject of `Class` which means that, while each `Class` object is indeed `sizeof(Class)` bytes long, the `IClass` pointer will almost certainly be offset to point _within_ the `Class` object somewhere (wherever the `IClass` object is stored). – cdhowie Jul 25 '20 at 15:04
  • I have edited my question, can you please see if you have anything in mind with that? – geo10 Jul 25 '20 at 15:31
  • 2
    The array is unable to contain Class objects. [What is object slicing?](https://stackoverflow.com/questions/274626/what-is-object-slicing) – 273K Jul 25 '20 at 15:44
  • 2
    @geo10 Polymorphism requires pointers/references. You can't store a `Class` in that array at all. Generally the way you make a list of owned polymorphic objects is `std::vector>` for example. As an aside, your base type `IClass` should have a virtual destructor if the program is ever going to `delete` an `IClass*`, or there is UB. – cdhowie Jul 25 '20 at 17:20

1 Answers1

1

how does the runtime store sizeof(Class) into something that have sizeof(IClass) allocated for it?

It does not. By assigning a Class instance to an element of the IClass array you are effectively invoking the IClass copy-constructor and copying just the parent part of the object. This is called "slicing", as explained in this answer.

In order to avoid it, you need to hold pointers (or references) to IClass. Three problems arise then:

  • You cannot copy the actual values, only move them or reference them, unless you implement a virtual "clone" method for your class hierarchy.
  • You need to handle ownership: an array of class C owns its instances, but an array of C* or C& does not. Normally you would want to use unique_ptr<T> or shared_ptr<T>, depending on the lifetime that is expected for the instances and who will see them.
  • You need a way to polymorphically construct and destroy the elements. The latter is easy, you just declare the destructor virtual at the base class. The former usually involves either somebody else passing you the instances they want saved (e.g. using an unique_ptr<IClass> that gives you the ownership) or creating some sort of factory infrastructure.
Javier Martín
  • 2,537
  • 10
  • 15