0

I receive the following error on declaring a vector of Point in the code shown (see reference to class template instantiation std::vector<Point,std::allocator<Point>> being compiled):

Severity Code Description Project File Line Suppression State Error C2558 class 'Point': no copy constructor available or copy constructor is declared 'explicit' AI assignment 1 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\xmemory 671

#include <iostream>
#include<vector>
using namespace std;

int dx, dy, sx, sy;

class Point
{
public:
    int x;
    int y;
    float g;
    float h;

    Point()
    {}
    Point(int s, int d)
    {
        x = s;
        y = d;
        h = pow(pow(x - dx, 2) + pow(y - dy, 2), 1 / 2);

    }
    Point(Point &p)
    {
        x = p.x;
        y = p.y;
        g = p.g;
        h = p.h;
    }

    bool operator == (Point p)
    {
        if (p.x == x && p.y == y)
            return true;
        else
            return false;
    }

};

class RoutePlaner
{
    vector<vector<char>>grid;
    int mapsize;
    Point start;
    Point destination;
    int no_of_obstacles;
    vector<Point> obstacles;

    void generate_random_obstacles(int num)
    {
        for (int i = 0; i < num; i++)
        {
            int k = rand() % mapsize;
            int j = rand() % mapsize;
            Point p(i, j);
            grid[j][k] = 'X';
            obstacles.push_back(p);
        }
    }
    
public:
    RoutePlaner(int m, Point s, Point d, int no)
    {
        mapsize = m;
        start = s;
        destination = d;
        no_of_obstacles = no;

        vector<char> vec(mapsize, '.');
        for (int i = 0; i < mapsize; i++)
        {
            grid.push_back(vec);
        }

        //Setting start and destination
        grid[start.x][start.y] = 'S';
        grid[destination.x][destination.y] = 'D';

        // setting obstacles
        generate_random_obstacles(no_of_obstacles);


    }
};

int main()
{

}

How should I declare a vector of class objects? How do I resolve the error?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Hizafa
  • 81
  • 1
  • 8
  • 2
    Not sure if that causes the problem, but a copy-ctor should take it's parameter by const reference. – Lukas-T Apr 24 '21 at 12:47
  • you made constant `Point`s non-copyable, because `Point(Point &p)` only accepts non-const `Point`s. See here: https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading – 463035818_is_not_an_ai Apr 24 '21 at 12:49
  • 1
    fwiw, the lesson to learn here is: make everything `const` by default, only non-const when it needs to be modified. – 463035818_is_not_an_ai Apr 24 '21 at 12:50

1 Answers1

3

You need your copy constructor for the Point class to conform to what std::vector (and many other aspects of the STL and C++ language) expects: that means its argument should be a const reference:

    Point(const Point& p)
    {
        x = p.x;
        y = p.y;
        g = p.g;
        h = p.h;
    }

Although, in your case, as pointed out in the comment by M.M, the compiler-generated copy constructor will do exactly the same job as yours, so you can just omit your 'explicit' version. Furthermore, if you do declare your own copy constructor, you should also declare a destructor and an assignment operator, in order to follow to "Rule of Three." (Or you can 'meet halfway' by explicitly declaring the default copy constructor: Point(const Point& p) = default;.)


Note, also, that you can simplify your operator == function: whenever you have code of the form, if (x) return true; else return false; you should consider using just return (x);, like this:

    bool operator == (Point p) {
        return (p.x == x && p.y == y);
    }
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • A better solution would be to remove this function from the code and allow the implicitly generated copy constructor. https://en.cppreference.com/w/cpp/language/rule_of_three – M.M Apr 24 '21 at 13:25
  • @M.M Good point - I was more concerned with a 'quick correction'. I have incorporated your comment into the answer, making it (hopefully) a better reference. – Adrian Mole Apr 24 '21 at 13:34