How to initialize an array and pass a pointer to the base constructor from a derivative?

Reformulated the question completely. Please read carefully

A separate note not to confuse you: the base constructor expects a pointer to an array of constants. It does not store the pointer itself, it stores data!

I have the following code:

class Base { public: Base(int*); // added this to explain why I need inheritance virtual void abstractMethod() = 0; }; Base::Base(const int *array) { // just for example cout << array[0] << endl; cout << array[1] << endl; cout << array[2] << endl; } class Derived : private Base { public: Derived(); void abstractMethod(); }; // who will delete? how to initialize? Derived::Derived(): Base(new int[3]) { } 

I want to hide the Base (int *) constructor from a user of my Derived class. To do this, I need to specify default values ​​for this array.

The problem is that when I use the initialization list as follows:

 Derived::Derived(): Base(new int[3]) { } 

the array is not initialized, and the base constructor prints some garbage. Another problem with this code: who will free this new array?

How to initialize an array before passing it to the base class? Is it even possible in C ++?

+4
source share
6 answers

I came to another solution:

 class Int3Array { int array[3]; public: Int3Array(int v1, int v2, int v3) { array[0] = v1; array[1] = v2; array[2] = v3; } int* getPtr() { return array; } }; Derived::Derived(): Base((Int3Array(1,1,1)).getPtr()) { } 

What do you think? Is it also bad?

0
source

Short answer: you cannot (unless you want to rely on possible quirks in a particular compiler). For standard compliance, Base must be fully constructed before anything else in Derived can be safely touched.

Focus instead of what you are trying to achieve. Why the array should be in Derived ; why do you feel the need to let Base initialize? There are probably dozens of safe ways to achieve what you need.

+4
source

This is a really bad design. Why do you need a constructor that accepts int* in your Base class when there is no element to initialize?
Taken from your comment on Pontus' answer, it seems you are aware of this flaw.

 class Base { private: int array[3]; public: Base(int* arr); virtual ~Base(); }; class Derived : Base { public: Derived(); }; 

Then you pass the array back to the base class using initialization lists:

 Derived() : Base(new int[3]) { array[0] = array[1] = array[2] = 1; } 

Basically, you call the class Base constructor and pass a parameter. And the Base constructor will also use the initialization list:

 Base(int* arr) : array(arr) { } 

In addition, when the Derived constructor starts, the Base object is already fully initialized, as promised by the standard.
Of course, you have to handle the destruction of your dynamically allocated array in Base :

 virtual ~Base(){ delete [] array; } 

Greetings.

+1
source

You can use the static function to generate your objects:

 class Base { public: Base(int*); }; class Derived : Base { public: static Derived createDerived() { int *a= new int[3]; a[0]=a[1]=a[2]=1; return Derived(a); } ~Derived() { delete [] array; } private: int *array; Derived(int * a):arrary(a),Base(a) { } }; 
+1
source

Found a solution:

 Derived::Derived(): Base(new int[3]{1,1,1}) { } 

But, alas, this is true only in C ++ 0x. g ++ gives me a warning:

 warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x 
0
source

The best solution I could find at this point is to use a static array:

 class Derived : private Base { public: Derived(); void abstractMethod(); static int array[3]; }; int Derived::array[3] = {5, 5, 5}; Derived::Derived(): Base(array) { } 

Feel free to add comments.

0
source

Source: https://habr.com/ru/post/1338226/


All Articles