0

I am working on a program that has a grid of object pointers that point to either a Null value or a derived child. I want to be able to set values on this grid to the address of their derived child such that I can "place" a child on the grid and access the child through their location in memory.

Heres what the interface looks like for the grid.

class Grid{

public:
    virtual int get(g_type) const;

public:

    parent* operator() (int,int);

    Grid() : _amtCol(10),_amtRow(10)
    {construct();}

    ~Grid() {deconstruct();}

private:
    int _amtCol;
    int _amtRow;
    parent* **_grid;

private:
    parent ***meddle(access);
    void meddle(access, parent***);
    virtual void construct();
    virtual void deconstruct();
};

Heres what the () overload looks like.

parent* Grid::operator() (int i,int j){

    if(i < get(r_QTY) && j < get(c_QTY)){

        return this->meddle(key)[i+1][j+1];

    }else{return NULL;}
}

What I want to be able to do is call this within the rest of my program as:

Grid b;
Child c;
Child c2;

b(1,1) = &c;
b(1,4) = &c2;

b(1,1)->foo(); //calls the first Childs foo()
b(1,4)->foo(); //calls the second Childs foo()

The rest of my classes are created and work as far as inheritance and structure go.

Is there a way that I could chain the overloads or something such that this works?

I thought that perhaps I needed to iron out my assignment overloads in the parents and child class's but they seem to work great.

/////////////////////////////////////////////////////

An aside, I do have this implemented:

void Grid::operator() (int i,int j,parent &cpy){
    if(i < get(r_QTY) && j < get(c_QTY)){
        this->meddle(key)[i+1][j+1] = &cpy;
    }
}

That does allows for this functionality.

There is my dissertation! Thanks!

////////////A quick addition: So perhaps I don't necessarily need to know if this is morally and ethically just. I have a way to implement the functionality that works. I guess I do understand that using something that already exists in a library is to be preferred over my own creations but the fact that it is do-able if you use a std::vector for example means that it is possible. I am wondering how this is made possible and where it exists in the language's syntax.

Burns
  • 19
  • 3
  • Unrelated, but you may find it useful to [learn why you shouldn't call `virtual` functions in the constructor or destructor](https://stackoverflow.com/questions/962132/calling-virtual-functions-inside-constructors) – Tas Nov 24 '17 at 00:40
  • Also, [why your destructor should be virtual](https://stackoverflow.com/questions/1123044/when-should-your-destructor-be-virtual) – PaulMcKenzie Nov 24 '17 at 00:45
  • Oh wow, that is super useful information. Thanks. – Burns Nov 24 '17 at 00:52
  • Also look up what a 3 star programmer is. – nwp Nov 24 '17 at 00:57
  • I don't understand why you used 3 levels of indirection (`parent ***`). What's the reason for triple pointers? – PaulMcKenzie Nov 24 '17 at 00:59
  • I was using it as a topographical data structure overlay to create a dynamically resizing 2 dimensional grid. . . .because I'm young and new to programming and as of yet still unaware of conventions and the reasons why inline implementations are preferred over indirection. – Burns Nov 24 '17 at 01:39
  • try solving this using a `std::vector>>`. – NathanOliver Nov 24 '17 at 01:47
  • are the cells in the grid polymorphic? – sp2danny Nov 24 '17 at 01:55
  • Yes. I'm unsure what way you would be specifically referencing but they are. – Burns Nov 24 '17 at 02:00

1 Answers1

0

Not sure exactly what is your question, but you can do something like:

struct parent
{
    virtual ~parent() = default;
    virtual void foo() = 0;
};

struct Child : parent
{
    Child(int n) : n(n) {}
    void foo() override { std::cout << n << std::endl;}
    int n;
};

class Grid{
public:
    Grid() : col(10), row(10), grid(col * row, nullptr) {}

    parent* operator() (std::size_t x, std::size_t y) const {
        if (col <= x || row <= y) { throw std::runtime_error("Invalid arguments"); }
        return grid[y * col + x];
    }

    parent*& operator() (std::size_t x, std::size_t y) {
        if (col <= x || row <= y) { throw std::runtime_error("Invalid arguments"); }
        return grid[y * col + x];
    }

private:
    int col;
    int row;
    std::vector<parent*> grid;
};

And then you have:

Grid b;
Child c(1);
Child c2(2);

b(1,1) = &c;
b(1,4) = &c2;

b(1,1)->foo(); //calls the first Childs foo()
b(1,4)->foo(); //calls the second Childs foo()

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302