13

If I have a base class, with only virtual methods and 2 derived classes from the base class, with those virtual methods implemented.

How do I:

 // causes C2259
 BaseClass* base = new BaseClass[2];

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

or:

// causes "base is being used without being initialized"
BaseClass* base;
// causes CC59 again
BaseClass* base = new BaseClass;

base[0] = FirstDerivedClass();
base[1] = SecondDerivedClass();

(or something similar)

...so that I can access the BaseClasss methods through the DerivedClass, but by pointer and the pointer is an array of DerivedClasss?

5 Answers 5

14

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.

Sign up to request clarification or add additional context in comments.

5 Comments

The problem, which is called "object slicing", is not specific to arrays -- it happens any time you assign a derived class to a base class by value. E.g. BaseClass b; b = FirstDerivedClass(); is compilable C++ that nevertheless breaks silently (at best you might get a compiler warning).
Link seems to be moved.
@Jon You sir, just saved my day. I had declared an array of objects of an inherited class (with virtual functions) and expected it to work. In your answer, however, what does BaseClass[0] = new FirstDerivedClass; do? Did you mean base[0] = new FirstDerivedClass;?
Ya I haven't tried this yet, but it seems like is should be base[0]= not BaseClass[0] = . It's array of objects not an array of classes.
@user3015682 right, fixed. Not sure why it took all of us many years to spot!
6

It is C++ use std::vector instead of simple array:

std::vector<BaseClass*> base;
base.push_back(new FirstDerivedClass());
base.push_back(new SecondDerivedClass());

As Kerrek SB noticed safest method is to use std::unique_ptr:

std::vector<std::unique_ptr<BaseClass> > base;
base.push_back( std_unique_ptr<BaseClass>(new FirstDerivedClass()) );
base.push_back( std_unique_ptr<BaseClass>(new SecondDerivedClass()) );

5 Comments

What for? Speed? Reliability?
What about: BaseClass* Base[2];Base[0] = new FirstDerivedClass; Base[1] = new SecondDerivedClass;
Using a vector is a good idea, but that's not the problem with the current code.
Even betterer is a std::vector<std::unique_ptr<BaseClass>>.
The crucial point here is to avoid object slicing by using pointers to BaseClass instead of BaseClass objects. Please emphasise that.
2

If your BaseClass contains pure virtual methods, this will fail to compile :

BaseClass* base = new BaseClass[2];

If it doesn't, you are going to get memory leak.

In c++, this is done by using std::vector or std::array, with some kind of smart pointer. For example :

std::vector< std::shared_ptr< BaseClass > > arr( 2 );
arr[0].reset( new FirstDerivedClass() );
arr[1].reset( new SecondDerivedClass() );

2 Comments

An even more important problem with the OP's code is object slicing, which breaks programs silently.
@j_random_hacker That is why I suggested to use some kind of smart pointer. Storing objects of base type (if it has no pure functions) would cause slicing
0

This was the answer (from Rubby)

BaseClass* Base[2];

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

2 Comments

This does something very different than what your original code was trying to do. This array is allocated on the stack, while originally it was on the heap.
Yes, I guess. Now the array is a pointer and there's pointers in the array.
0

Define a pointer array , the pointer type is BaseClass. And assign the pointer to the derivedclass to the elements of the array. just like:

BaseClass* base [2];
base[0] = new FirstDerivedClass;
base[1] = new SecondDerivedClass;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.