Search code examples
c++vectorgraph

how to use vector to store a shape?


I first create a window, and I create a series of rectangles and put them into a vector, then comes to the problem. The code can not build. But I don't know why. Is that I can not use vector in this way"vector rect;"

#include <vector>
#include<string>
#include "Graph.h" // get access to our graphics library facilities
#include "Simple_window.h" 
int main()
{

Graph_lib::Point tl{ 100, 100 }; 

Simple_window win{ tl, 1000, 800, "Simple Window" }; 

int x_size = 800;
int y_size = 800;

using namespace std;
vector<Graph_lib::Rectangle> rect;//error
for (int x = 0, y = 0; x < x_size&&y < y_size; x += x_grid, y += y_grid)
{
    Graph_lib::Rectangle r(Graph_lib::Point(x, y), x_grid, y_grid);
    r.set_fill_color(Graph_lib::Color::red);
    rect.push_back(r);
}

for (int i = 0; i < 8; i++)
    win.attach(rect[i]);
win.attach(grid);
win.wait_for_button(); 

return 0;
}

D:\Visual Studio Community 2017\VC\Tools\MSVC\14.11.25503\include\xmemory0(856): error C2280: 'Graph_lib::Rectangle::Rectangle(const Graph_lib::Rectangle &)': attempting to reference a deleted function

D:\VS_practice\ChengLu_C13Drill\include\Graph.h(311): note: compiler has generated 'Graph_lib::Rectangle::Rectangle' here

D:\Visual Studio Community 2017\VC\Tools\MSVC\14.11.25503\include\vector(958): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,const _Ty&>(_Alloc &,_Objty *const ,const _Ty &)' being compiled
        with
        [
            _Alloc=std::allocator<Graph_lib::Rectangle>,
            _Ty=Graph_lib::Rectangle,
            _Objty=Graph_lib::Rectangle
        ]

D:\Visual Studio Community 2017\VC\Tools\MSVC\14.11.25503\include\vector(958): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,const _Ty&>(_Alloc &,_Objty *const ,const _Ty &)' being compiled
        with
        [
            _Alloc=std::allocator<Graph_lib::Rectangle>,
            _Ty=Graph_lib::Rectangle,
            _Objty=Graph_lib::Rectangle
        ]

D:\Visual Studio Community 2017\VC\Tools\MSVC\14.11.25503\include\vector(981): note: see reference to function template instantiation 'void std::vector<T,std::allocator<_Ty>>::emplace_back<const _Ty&>(const _Ty &)' being compiled
        with
        [
            T=Graph_lib::Rectangle,
            _Ty=Graph_lib::Rectangle
        ]

D:\Visual Studio Community 2017\VC\Tools\MSVC\14.11.25503\include\vector(980): note: while compiling class template member function 'void std::vector<T,std::allocator<_Ty>>::push_back(const _Ty &)'
        with
        [
            T=Graph_lib::Rectangle,
            _Ty=Graph_lib::Rectangle
        ]

D:\VS_practice\ChengLu_C13Drill\src\main.cpp(32): note: see reference to function template instantiation 'void std::vector<T,std::allocator<_Ty>>::push_back(const _Ty &)' being compiled
        with
        [
            T=Graph_lib::Rectangle,
            _Ty=Graph_lib::Rectangle
        ]

d:\vs_practice\chenglu_c13drill\include\std_lib_facilities.h(72): note: see reference to class template instantiation 'std::vector<T,std::allocator<_Ty>>' being compiled
        with
        [
            T=Graph_lib::Rectangle,
            _Ty=Graph_lib::Rectangle
        ]

D:\VS_practice\ChengLu_C13Drill\src\main.cpp(27): note: see reference to class template instantiation 'Vector<Graph_lib::Rectangle>' being compiled

D:\VS_practice\ChengLu_C13Drill\include\Graph.h(311): note: 'Graph_lib::Rectangle::Rectangle(const Graph_lib::Rectangle &)': function was implicitly deleted because a base class invokes a deleted or inaccessible function 'Graph_lib::Shape::Shape(const Graph_lib::Shape &)'

D:\VS_practice\ChengLu_C13Drill\include\Graph.h(232): note: 'Graph_lib::Shape::Shape(const Graph_lib::Shape &)': function was explicitly deleted

Build failed.


Solution

  • It appears that the Graph_lib::Rectangle class is not copyable, because its copy constructor is deleted. This prevents you from using push_back() directly on an instance. You might be able to use std:move():

    rect.push_back(std::move(r));
    

    It's possible the class is not moveable either. In this case, you could use std::unique_ptr in the vector:

    vector<std::unique_ptr<Graph_lib::Rectangle>> rect;
    

    This will require you to dynamically allocate your objects. This can be done using std::make_unique if your compiler supports the C++14 standard or later:

    for (int x = 0, y = 0; x < x_size&&y < y_size; x += x_grid, y += y_grid)
    {
        auto r = std::make_unique<Graph_lib::Rectangle>(Graph_lib::Point(x, y), x_grid, y_grid);
        r->set_fill_color(Graph_lib::Color::red);
        rect.push_back(std::move(r));
    }
    

    If C++14 is not available, you can allocate your rectangles using new:

    for (int x = 0, y = 0; x < x_size&&y < y_size; x += x_grid, y += y_grid)
    {
        auto r = std::unique_ptr<Graph_lib::Rectangle>(new Graph_lib::Rectangle(Graph_lib::Point(x, y), x_grid, y_grid));
        r->set_fill_color(Graph_lib::Color::red);
        rect.push_back(std::move(r));
    }