Ошибка C2280 / Проблема с конструктором копирования при создании экземпляра объекта в std :: vector? - PullRequest
0 голосов
/ 09 октября 2019

В настоящее время я программирую свое первое приложение, следуя инструкциям ChiliTomatoNoodle, и модифицирую его код в соответствии с моими потребностями. При этом и реализации простого класса WindowManager, целью которого является сохранение всех экземпляров окна в std :: vector и аналогичных вещах, я получил следующее сообщение об ошибке:

C: \ Program Files(x86) \ Microsoft Visual Studio \ 2019 \ Community \ VC \ Tools \ MSVC \ 14.23.28105 \ include \ xmemory (758,1):

ошибка C2280: 'Window :: Window (const Window &)': попытка сослаться на удаленную функцию (компилирование исходного файла src \ cpp \ WindowManager.cpp)

Проблема, похоже, заключается в функции addWindow, где окно создается и сохраняется в std::vector<Window> Wnd:

void WindowManager::addWindow(unsigned short x, unsigned short y, unsigned short width, unsigned short height, const char* name, Window::WindowClass& windowClass, DWORD style) {

    this->Wnd.emplace_back(Window(name, x, y, width, height, windowClass, style, this->IdGenNum++));
}

Я уже изменил push_back на emplace_back, чтобы, возможно, избежать копирования (?), Но это не решило проблему.

Тогда есть и геттер(это нормально и ничего не копируется):

Window& WindowManager::getWindow(const unsigned short id) {

    for (Window &element : this->Wnd) {

        if (element.Id == id) {

            return element;
        }
    }
}

А вот заголовок класса Window:

class Window {

private:    // Friends

    friend class WindowManager;

public:     // Nested Classes

    class WindowClass {

        ...
    };

private:    // Variables and Instances

    unsigned short Id;    // Received by WindowManager on Creation

    const char* Name;

    HWND Handle;

    ...

public:     // Constructors and Deconstructors

    Window(const Window&) = delete;

    Window(

        const char* name,
        unsigned short x, 
        unsigned short y, 
        unsigned short width, 
        unsigned short height,  
        WindowClass& windowClass, 
        DWORD style,
        unsigned short id
    );

    ~Window();


private:    // Functions

    ...

public:     // Operators

    Window& operator=(const Window&) = delete;
};

Редактировать:

Спасибо за все ответы и комментарии, указывающие на то, что аргументы должны быть переданы напрямуюк методу emplace_back. Как оказалось, вектор все еще копировал объект (понятия не имею, почему ..), но я мог бы исправить это, используя вместо этого std::list, который не имеет такого поведения.

Ответы [ 2 ]

1 голос
/ 09 октября 2019

Конструктор копирования Window объявлен с delete, но когда вы передаете существующий объект Window в emplace_back(), реализация emplace_back() попытается использовать его аргументы для создания другого объекта Windowна месте. Единственный способ сделать это - попытаться использовать конструктор удаленных копий.

Вы можете объявить конструктор копирования, использовать push_back() или, что еще лучше, вызвать emplace_back(), используя аргументы для других Window конструктор, который позволит избежать копирования.

0 голосов
/ 09 октября 2019

Эта строка создает временное окно, которое будет перемещено (если есть конструктор перемещения) или скопировано (если есть конструктор копирования) в vector - но вашему Window не хватает обоих:

this->Wnd.emplace_back(Window(name, x, y, width, height, windowClass, style,
                              this->IdGenNum++));

С emplace_back вам не нужно создавать временный объект, поскольку аргумент, который вы даете emplace_back, идеально перенаправляется в конструктор Window, поэтому не будет ненужного перемещения или копирования:

this->Wnd.emplace_back(name, x, y, width, height, windowClass, style, this->IdGenNum++);

Хотя этого должно быть достаточно для решения этой непосредственной проблемы, ваш класс Window выглядит так, как будто он должен поддерживать перемещение, но не обязательно копирование.

...