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 Shape
s 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
Assembly Adc (Add with Carry) to C++
The C 'Clock()' Function Just Returns a Zero
Decimal to Hex Conversion C++ Built-In Function
Using C Function from Other Package in Rcpp
Printf Rounding Behavior for Doubles
Address-Of Operator (&) VS Reference Operator(&)
Where Are Member Functions Stored for an Object
Why Is Std::Iterator Deprecated
Get Function Names from Call Stack
Structured Binding with [[Maybe_Unused]]
Why "Initializer-String for Array of Chars Is Too Long" Compiles Fine in C & Not in C++
New (Std::Nothrow) VS. New Within a Try/Catch Block
What Encoding Does Std::String.C_Str() Use
What Exactly Is or Was the Purpose of C++ Function-Style Casts