querying_questioner
querying_questioner

Reputation: 11

C++ Initializing Member Variables that are Containers of Object Pointers

I apologize to ask this as I'm sure it's been answered elsewhere. I am trying to initialize a container of object pointers within the constructor of my class. The container is an array template, the class for the constructor is A and the object type is class P.

A.cpp:
    #include 'Array.h'
    #include 'P.h'

    
    A::A(){
    Array<P*> ps = ?

P.cpp:
   P::P(string n){
      this->name = n;
   }


Array.h:

using namespace std;

template <typename T>
class Array {

    public:
        Array();
                
        ~Array();
        void add(int);
        int get(int index);
        int getSize();
        bool isFull();
        int& operator[] (int);
    
    private:
        int size;
        int* elements;
        static int MAX_ARR = 256;
    
};
template <typename T>
Array<T>::Array(){
    elements = new int[MAX_ARR];
    size = 0;
}
template <typename T>
Array<T>::~Array(){
    delete [] elements;
}
template <typename T>
void Array<T>::add(int t){
    if (size >= MAX_ARR)   return;
    elements[size++] = t;
}
template <typename T>
int Array<T>::getSize(){
    return size;
}
template <typename T>
bool Array<T>::isFull(){
    return size >= MAX_ARR;
}
template <typename T>
int& Array<T>::operator[](int index){
    if (index < 0 || index >= size) {
        cerr<<"Array index out of bounds"<<endl;
        exit(0);Array
    }
    return elements[index];
}

wondering what should go in the question mark/ how to properly initialize said member variable. Class P is simple, has a single string as a parameter for it's constructor.

Upvotes: -2

Views: 459

Answers (1)

UncleBen
UncleBen

Reputation: 82

Note: By the nature of your question, I'm assuming you're not too familiar with some of the initialization syntax of C++. Apologies if this is not the case and I'm misunderstanding your question.

If you only want your ps variable to be initialized, then you can simply call the default constructor using that syntax:

A::A()
{
    // This will call the Array default constructor. There is no need for "= <something>"
    Array<P*> ps;
}

After that declaration the ps array is already initialized and you can add elements to it right away. (However if you say that its a member variable, then you don't even need that line, the ps default constructor will be called before you enter the A constructor body.) This can be a bit counter intuitive if you come from a Java or C# background, as in those language the variable would be uninitialized with that syntax. However in C++ you have control over if the variables are initialized on the heap or on the stack.

Heap initialization: Array<P*>* ps = new Array<P*>();

Stack initialization: Array<P*> ps(); //you can also remove the () and the default constructor will be implicitly called

More familiar stack initialization: Array<P*> ps = Array<P*>() That one can be bit inefficient as a temporary Array is first created and then it is moved/copied to the ps variable. This is technically slower, but modern compilers can often optimize away that additional step and simply construct the Array in-place. Edit: In your case that syntax is not available because you defined a custom destructor in your Array class, no copy and move assignment operators will be auto-generated. You would need to manually implement them first.

If you were wondering instead how to construct the array directly with its content, then I suggest you have a look at std::initializer_list. By adding a constructor supporting an initializer_list to your Array class, you would then be able to use the following syntax.

A::A()
    // Assuming your string object can be constructed in such way.
    : ps({new P(string("foo")), new P(string("bar"))})
{}

Upvotes: 0

Related Questions