Search code examples
c++classmultidimensional-arraydynamically-generated

Class that uses dynamically generated array


Trying to make a class that can change the contents of a specific element in a dynamically created 2 dimensional array of strings.

So I have a program that creates a 2d array dynamically and later on I want to have a class that takes that array as its argument, along with 2 integers that will be the indexes of a specific element. Later on I'll have it swap the content of that element and scan other elements of the array that it wants to swap it with. For now I'm struggling with even having the class take that array as its argument. I know I'll have to do this by reference and not by value, since the array will be dynamically created, but it seems I am doing it wrong.

#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

class Example {
    int x, y;
    string** chart;
public:

    Example(int i, int j,string **arr);
    void print() const { cout << x << y << chart[x][y] << endl; }

};

Example::Example(int i, int j,string **arr) {
    x = i;
    y = j;
    **chart = **arr;
}

int main() {

    string chart[7][7]; //to make the experiment simpler I haven't 
                        //made the array dynamically generated yet
                        //but it will be later

    for (int i = 0; i < 7; i++) {
        for (int j = 0; j < 7; j++) {
            if (chart[i][j] == "")
                chart[i][j].insert(0, 3, '  ');
        }
    }

    chart[6][5] = "EXA";

    for (int i = 0; i < 7; i++) {
        for (int j = 0; j < 7; j++) {
            cout << '[' << chart[i][j] << ']';
        }
        cout << endl;
    }

    Example Exa1(6, 5, &chart);
    Exa1.print();

    return 0;
}

Solution

  • The problem is that the type of &chart is std::string (*)[7][7] which cannot be implicitly converted to a string** and so the constructor Example::Example(int i, int j,string **) cannot be used. This is exactly what the mentioned error says:

     error: no matching function for call to 'Example::Example(int, int, std::string (*)[7][7])'
       45 |     Example Exa1(6, 5, &chart);
    

    To solve this make sure that &chart has the same type as the 3 parameter of your constructor.

    Also it would be better to use std::vector.

    class Example {
        int x, y;
        std::vector<std::vector<string>> chart;
    public:
    
        Example(int i, int j,const std::vector<std::vector<std::string>> &arr);
        
    };
    
    Example::Example(int i, int j,const std::vector<std::vector<std::string>> &arr)
       :x(i),y(j),chart(arr) {
      
    }
    
    int main() {
    
        std::vector<std::vector<std::string>> chart(7, std::vector<std::string>(7)); 
        //pass chart instead of &chart
        Example Exa1(6, 5, chart);
    
    }
    

    Working demo


    Or you can also use std::array

    class Example {
        int x, y;
        std::array<std::array<std::string, 7>, 7> chart;
    public:
    
        Example(int i, int j,const std::array<std::array<std::string, 7>, 7> &arr);
        
    };
    
    Example::Example(int i, int j,const std::array<std::array<std::string, 7>, 7> &arr)
       :x(i),y(j),chart(arr) {
      
    }
    
    int main() {
    
        std::array<std::array<std::string, 7>, 7> chart;
        //pass chart instead of &chart
        Example Exa1(6, 5, chart);
    
    }