0

I have 3 files. main.cpp, object.h, and object.cpp.

In main I am trying to create an array of 100 object pointers. Then, after creating the array I enter a loop and go through each 'i' element and assign the value of that element as the pointer to a new temporary object which will be passed in a string. The basic premise of this is that I can use this to store multiple objects which have information inside them, information that I can print afterwards by calling a function on those points. I'm required to use an array of pointers to do so.

In essence, I want to store data in an array of object pointers which will use a new operator to store it each iteration. However, I'm not sure how to even create the array since it needs to be passed in variables to be called.

I've tried Object *ptr = new Object[arraySize]; and I was sure that would work but it expects arguments since the object is defined to take variables inside it.

main.cpp

#include <iostream>
#include "object.h"

int main()
{
    Object *ptr = new Object[5];
    for(i = 0; i < 5, i++) {
        ptr[i] = "Test";
        ptr -> print();
    }

}

object.cpp

#include "object.h"
#include <iostream>

using namespace std;

Object::Object(string words)
{
    private_words = words;
}

void Object::print()
{
    cout << private_words << endl;
}

object.h

#ifndef OBJECT_H
#define OBJECT_H

#include <string>

using namespace std;

class Object
{

    public:
        Object(string words);
        void print();
    private:
        string private_words;
};

#endif

I got multiple unintelligible errors about the fact that I tried to pass in arguments and make it an array at the same time. Object *ptr = new Object()[5] didn't work.

Jaskal
  • 37
  • 1
  • 9
  • To create an array of 100 object pointers (something you ask for in the question but I'm not certain you really want), `Object *ptr[100];`. Note that these 100 pointer are not initialized and currently point somewhere that's not defined. Do not try to dereference a pointer (get the object at the pointer) until you have pointed it a valid `Object` instance (probably created with `new`, but [try to avoid `new` where possible](https://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new)). – user4581301 Feb 19 '19 at 03:02

1 Answers1

1

Your Object class lacks a default constructor, which is why new Object[...] will not work. You will have to use something more like this instead:

#include <iostream>
#include "object.h"

int main()
{
    Object **ptr = new Object*[5];
    for(i = 0; i < 5, i++) {
        ptr[i] = new Object("Test");
    }

    // use ptr as needed ...

    for(i = 0; i < 5, i++) {
        ptr[i]->print();
    }

    // cleanup ...

    for(i = 0; i < 5, i++) {
        delete ptr[i];
    }
    delete[] ptr;
}

Better would be to use standard containers instead and let the compiler manage the memory for you.

Prior to C++11:

#include <iostream>
#include <memory>
#include "object.h"

int main()
{
    // NOTE: std::auto_ptr is NOT a container-safe type...
    std::auto_ptr<Object>* ptr = new std::auto_ptr<Object>[5];
    for(i = 0; i < 5, i++) {
        ptr[i].reset(new Object("Test"));
    }

    // use ptr as needed ...

    for(i = 0; i < 5, i++) {
        ptr[i]->print();
    }

    // cleanup ...
    // only the array is needed manually, the individual elements
    // will clean themselves up when they are destructed ...

    delete[] ptr;
}

In C++11 and later, use this instead:

#include <iostream>
#include <vector>
#include <memory>
#include "object.h"

int main()
{
    // NOTE: std::unique_ptr IS a container-safe type...
    std::vector<std::unique_ptr<Object>> ptr(5);
    for(i = 0; i < 5, i++) {
        ptr[i].reset(new Object("Test"));

        // or:
        // ptr[i] = std::unique_ptr<Object>(new Object("Test"));

        // or, in C++14 and later:
        // ptr[i] = std::make_unique<Object>("Test");
    }

    // use ptr as needed ...

    for(i = 0; i < 5, i++) {
        ptr[i]->print();
    }

    // all cleanup is automatic when ptr goes out of scope ...
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • What are you doing by writing Object **ptr = new Object*[5]; ? You're getting the value of pointer which is a pointer? I'm a little bit confused on how that's supposed to work. Would adding a default constructor for the Object class be a better solution? How would I do that if so? – Jaskal Feb 19 '19 at 03:47
  • 1
    @Jaskal `new` returns a pointer to the memory it allocates. `new T` allocates a single `T` and returns a `T*` pointer. `new T[]` allocates an array of `T` and still returns a `T*` pointer. In my 1st example, `T` is `Object*`, so `new Object*[5]` allocates an array of 5 `Object*` pointers and returns an `Object**` pointer to the array. – Remy Lebeau Feb 19 '19 at 09:31
  • 1
    @Jaskal Adding a [default constructor](https://en.cppreference.com/w/cpp/language/default_constructor) will allow you to use things like `Object *arr = new Object[5]`, `Object arr[5]`, `std::vector arr(5)`, etc, so it is good to have. But it won't help you understand pointers. – Remy Lebeau Feb 19 '19 at 09:31