开发者

Array of polymorphic base class objects initialized with child class objects

Sorry for the complicated title. I have something like this:

class Base
{
public:
  int SomeMember;
  Base() : SomeMember(42) {}
  virtual int Get() { return SomeMember; }
};

class ChildA : public Base
{
public:
  virtual int Get() { return SomeMember*2; }
};

class ChildB : public Base
{
public:
  virtual int Get() { return SomeMember/2; }
};

class ChildC : public Base
{
public:
  virtual int Get() { return SomeMember+2; }
};

Base ar[] = { ChildA(), ChildB(), ChildC() };

for (int i=0; i<sizeof(ar)/sizeof(Base); i++)
{
  Base* ptr = &ar[i];
  开发者_运维问答printf("El %i: %i\n", i, ptr->Get());
}

Which outputs:

El 0: 42
El 1: 42
El 2: 42

Is this correct behavior (in VC++ 2005)? To be perfectly honest, I expected this code not to compile, but it did, however it does not give me the results I need. Is this at all possible?


Yes, this is correct behavior. The reason is

Base ar[] = { ChildA(), ChildB(), ChildC() };

initializes array elements by copying objects of three different classes onto objects of class Base and that yields objects of class Base and therefore you observe behavior of class Base from each element of the array.

If you want to store objects of different classes you have to allocate them with new and store pointers to them.


To achieve polymorphic behaviour you expected, you should use array of pointers to Base and create objects via new:

Base* ar[] = { new ChildA(), new ChildB(), new ChildC() };


What is actually happening is that:

  1. Since the type of ar[] is Base, 3*sizeof(Base) amount of memory is allocated to ar.

  2. Since you have not declared an explicit copy constructor for Base, the default copy constructor of base is called which just bitwise copies the "Base" part of ChildA, ChildB and ChildC objects into the Base objects contained in the array ar( The default copy constructor is smart enough not to bitwise copy the virtual pointer of Child objects into the Base virtual pointer ).

  3. ar[0], ar[1] and ar[2]'s virtual pointers point to Base::Get so Base::Get is called.

The point to note here is that the function to which virtual pointer of an object will point is always known prior to the execution.

In this case, the runtime knew in advance that arr consists of "Base" objects, so it it set their vptr so as to point to Base::Get as soon as they were alotted memory.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜