Base Pointer to Array of Derived Objects

Base pointer to array of derived objects

If you look at the expression p[1], p is a Base* (Base is a completely-defined type) and 1 is an int, so according to ISO/IEC 14882:2003 5.2.1 [expr.sub] this expression is valid and identical to *((p)+(1)).

From 5.7 [expr.add] / 5, when an integer is added to a pointer, the result is only well defined when the pointer points to an element of an array object and the result of the pointer arithmetic also points the an element of that array object or one past the end of the array. p, however, does not point to an element of an array object, it points at the base class sub-object of a Derived object. It is the Derived object that is an array member, not the Base sub-object.

Note that under 5.7 / 4, for the purposes of the addition operator, the Base sub-object can be treated as an array of size one, so technically you can form the address p + 1, but as a "one past the last element" pointer, it doesn't point at a Base object and attempting to read from or write to it will cause undefined behavior.

initialize a base class pointer with an array of derived class objects

This will not work - C arrays do not know about the dynamic size of polymorphic types. If you want to use polymorphism, then you have to use arrays (preferably std::vector or another standard array, not a C array) of pointers (preferably smart pointers) to the base type.

Pointer to array of base class, populate with derived class

Your array is of the wrong type: it stores BaseClass object instances instead of pointers to them. Since BaseClass seems to be abstract, the compiler complains that it cannot default-construct instances to fill your array.

Even if BaseClass were not abstract, using arrays polymorphically is a big no-no in C++ so you should do things differently in any case.

Fix this by changing the code to:

BaseClass** base = new BaseClass*[2];

base[0] = new FirstDerivedClass;
base[1] = new SecondDerivedClass;

That said, most of the time it is preferable to use std::vector instead of plain arrays and smart pointers (such as std::shared_ptr) instead of dumb pointers. Using these tools instead of manually writing code will take care of a host of issues transparently at an extremely small runtime cost.

Can derived object pointers be stored in an array of base class pointers?

Can I store a derived class object pointer (derived from that base class) in this array?

Yes.

and can I do it the other way around?

No.

Say you have:

struct Base
{
};

struct Derived1 : Base
{
};

struct Derived2 : Base
{
};

std::vector<Derived1*> ptrs;
Base* bPtr = new Derived2;
ptrs.push_back(bPtr); // Not allowed.
// If it were, imagine the problems.
// You have a Derived2* in the guise of a Derived1*

Can a pointer to base point to an array of derived objects?

You cannot index like that. You have allocated an array of Rectangles and stored a pointer to the first in shapes. When you do shapes[1] you're dereferencing (shapes + 1). This will not give you a pointer to the next Rectangle, but a pointer to what would be the next Shape in a presumed array of Shape. Of course, this is undefined behaviour. In your case, you're being lucky and getting a crash.

Using a pointer to Rectangle makes the indexing work correctly.

int main()
{
Rectangle * shapes = new Rectangle[10];
for (int i = 0; i < 10; ++i) shapes[i].draw();
}

If you want to have different kinds of Shapes in the array and use them polymorphically you need an array of pointers to Shape.

Array of Pointers to Different Derived Classes

you are maintaining an array of channel obejcts.

For virtual function to work you need to maintain either pointer of base class type or a reference.

Channel *Channels;

creates an array of Channel obejcts. You need to create an array of pointer/reference to channel object i.e.

Channel **Channels;

Change the program accordingly to use pointer instead of object of channel type.



Related Topics



Leave a reply



Submit