#include <iostream>
#include <vector>

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;
};


int main() {
	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()
}