initialize member array with constructor

Viewed 55

I have a class School like this. Space is an abstract class, don't mind about it.

class school:public space
{

    private:
        schoolyard y;

        stairs s;
        floor floors[3];
        int capa;
    public:
        school(int x):floors[1](x),floors[2](x),floors[3](x){
         cout<<"a school has been created"<<endl;}
         void move(student x);
        ~school();

};

floor is another class which I want to initialize. This part floors[1](x),floors[2](x),floors[3](x) is probably wrong. Maybe someone know how I can initialize an array of objects in a class?

2 Answers

Should be:

school(int x) : floors{x, x, x}
{
    std::cout << "a school has been created" << std::endl;
}

First off, arrays are 0-based, so the valid indexes are 0-2, not 1-3.

Second, you can't initialize individual array members in a constructor's member initialization list like you are attempting to.

If floor does not have a default constructor, you can change your floors[] array to hold floor* pointers instead, and then construct each floor object using new in the constructor's body, eg:

class school : public space
{
    private:
        ...
        floor* floors[3];
        ...

    public:
        school(int x){
            for (int i = 0; i < 3; ++i){
                floors[i] = new floor(x);
            }
            // other initialization as needed...
            cout << "a school has been created" << endl;
        }

        ~school(){
            for (int i = 0; i < 3; ++i){
                delete floors[i];
            }
        }

        ...
};

Be aware that with this approach, you need to follow the Rule of 3/5/0, which means also implementing a copy constructor and a copy assignment operator, and optionally a move constructor and a move assignment operation in C++11 and later:

...
#include <algorithm>

class school : public space
{
    private:
        ...
        floor* floors[3];
        ...

    public:
        school(int x){
            for (int i = 0; i < 3; ++i){
                floors[i] = new floor(x);
            }
            // other initializations as needed...
            cout << "a school has been created" << endl;
        }

        school(const school &src){
            for (int i = 0; i < 3; ++i){
                floors[i] = new floor(*(src.floors[i]));
            }
            // other copies as needed...
            cout << "a school has been copied" << endl;
        }

        school(school &&src){
            for (int i = 0; i < 3; ++i){
                floors[i] = src.floors[i];
                src.floors[i] = nullptr;
            }
            // other moves as needed...
            cout << "a school has been moved" << endl;
        }

        ~school(){
            for (int i = 0; i < 3; ++i){
                delete floors[i];
            }
        }

        school& operator=(const school &rhs){
            if (this != &rhs){
                school temp(rhs);
                std::swap_ranges(floors, floors+3, temp.floors);
            }
            return *this;
        }

        school& operator=(school &&rhs){
            school temp(std::move(rhs));
            std::swap_ranges(floors, floors+3, temp.floors);
            return *this;
        }

        ...
};

However, a std::vector would make things much easier, letting the compiler handle all of these details for you, eg:

...
#include <vector>

class school : public space
{
    private:
        ...
        std::vector<floor> floors;
        ...

    public:
        school(int x): floors(3, floor(x)) {
            cout << "a school has been created" << endl;
        }

        ...
};
Related