【问题标题】:Abstract classes and unique pointers c++ error? [duplicate]抽象类和唯一指针 C++ 错误? [复制]
【发布时间】:2017-07-03 00:47:30
【问题描述】:

我在调试带有抽象类错误的std::vector<std::unique_ptr<>> 时遇到问题。据我所知,错误是尝试在std::unique_ptr 上使用vector.push_back()

Components.h

namespace cr {
    class Component {
    public:
        Component();
        virtual ~Component();
        virtual void draw() = 0;
        virtual void inflate(Frame frame) = 0;
    private:
        Frame _frame;
    };

    class ButtonComponent : public Component {
    public:
        void draw();
        void inflate(Frame frame);
    };
}

Components.cpp

void cr::ButtonComponent::draw()
{
}

void cr::ButtonComponent::inflate(cr::Frame frame)
{
}

cr::Component::Component()
{
}

cr::Component::~Component()
{
}

Window.h 窗口的一部分

class View {
        friend class ViewController;
    public:
        void render();
        void insert(std::unique_ptr<Component> component);
    protected:
        void inflate();
    private:
        Frame frame;
        std::vector<std::unique_ptr<Component>> _components;
    };

Window.cpp 窗口的一部分

void cr::View::render()
{
    for (auto& c : _components) {
        c->draw();
    }
}

void cr::View::insert(std::unique_ptr<Component> component)
{
    _components.push_back(component);
}

void cr::View::inflate() {
    for (auto& c : _components) {
        c->inflate(frame);
    }
}

错误输出

1>------ Build started: Project: test, Configuration: Debug Win32 ------
1>  RWindow.cpp
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(737): error C2280: 'std::unique_ptr<cr::Component,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function
1>          with
1>          [
1>              _Ty=cr::Component
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(1435): note: see declaration of 'std::unique_ptr<cr::Component,std::default_delete<_Ty>>::unique_ptr'
1>          with
1>          [
1>              _Ty=cr::Component
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(857): note: see reference to function template instantiation 'void std::allocator<_Ty>::construct<_Objty,std::unique_ptr<cr::Component,std::default_delete<cr::Component>>&>(_Objty *,std::unique_ptr<cr::Component,std::default_delete<cr::Component>> &)' being compiled
1>          with
1>          [
1>              _Ty=std::unique_ptr<cr::Component,std::default_delete<cr::Component>>,
1>              _Objty=std::unique_ptr<cr::Component,std::default_delete<cr::Component>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(857): note: see reference to function template instantiation 'void std::allocator<_Ty>::construct<_Objty,std::unique_ptr<cr::Component,std::default_delete<cr::Component>>&>(_Objty *,std::unique_ptr<cr::Component,std::default_delete<cr::Component>> &)' being compiled
1>          with
1>          [
1>              _Ty=std::unique_ptr<cr::Component,std::default_delete<cr::Component>>,
1>              _Objty=std::unique_ptr<cr::Component,std::default_delete<cr::Component>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(996): note: see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,std::unique_ptr<cr::Component,std::default_delete<cr::Component>>&>(std::allocator<_Ty> &,_Objty *,std::unique_ptr<cr::Component,std::default_delete<cr::Component>> &)' being compiled
1>          with
1>          [
1>              _Alloc=std::allocator<std::unique_ptr<cr::Component,std::default_delete<cr::Component>>>,
1>              _Ty=std::unique_ptr<cr::Component,std::default_delete<cr::Component>>,
1>              _Objty=std::unique_ptr<cr::Component,std::default_delete<cr::Component>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(995): note: see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,std::unique_ptr<cr::Component,std::default_delete<cr::Component>>&>(std::allocator<_Ty> &,_Objty *,std::unique_ptr<cr::Component,std::default_delete<cr::Component>> &)' being compiled
1>          with
1>          [
1>              _Alloc=std::allocator<std::unique_ptr<cr::Component,std::default_delete<cr::Component>>>,
1>              _Ty=std::unique_ptr<cr::Component,std::default_delete<cr::Component>>,
1>              _Objty=std::unique_ptr<cr::Component,std::default_delete<cr::Component>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(1284): note: see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Ty>>::construct<_Ty,std::unique_ptr<cr::Component,std::default_delete<cr::Component>>&>(_Ty *,std::unique_ptr<cr::Component,std::default_delete<cr::Component>> &)' being compiled
1>          with
1>          [
1>              _Ty=std::unique_ptr<cr::Component,std::default_delete<cr::Component>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(1283): note: see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Ty>>::construct<_Ty,std::unique_ptr<cr::Component,std::default_delete<cr::Component>>&>(_Ty *,std::unique_ptr<cr::Component,std::default_delete<cr::Component>> &)' being compiled
1>          with
1>          [
1>              _Ty=std::unique_ptr<cr::Component,std::default_delete<cr::Component>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector(1276): note: while compiling class template member function 'void std::vector<std::unique_ptr<cr::Component,std::default_delete<_Ty>>,std::allocator<std::unique_ptr<_Ty,std::default_delete<_Ty>>>>::push_back(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)'
1>          with
1>          [
1>              _Ty=cr::Component
1>          ]
1>  c:\users\matt\documents\game development\projects\crengine\test\rwindow.cpp(14): note: see reference to function template instantiation 'void std::vector<std::unique_ptr<cr::Component,std::default_delete<_Ty>>,std::allocator<std::unique_ptr<_Ty,std::default_delete<_Ty>>>>::push_back(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' being compiled
1>          with
1>          [
1>              _Ty=cr::Component
1>          ]
1>  c:\users\matt\documents\game development\projects\crengine\test\rwindow.h(19): note: see reference to class template instantiation 'std::vector<std::unique_ptr<cr::Component,std::default_delete<_Ty>>,std::allocator<std::unique_ptr<_Ty,std::default_delete<_Ty>>>>' being compiled
1>          with
1>          [
1>              _Ty=cr::Component
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

项目背景

一个简单的 GUI,它有一个窗口,一个包含多个视图的视图控制器。视图包含多个组件(也称为小部件)。项目过程中用到了SFML和OpenGL。

【问题讨论】:

  • std::unique_ptr 是不可复制的,请参阅this link。尝试在插入函数中通过引用传递unique_ptr 并尝试push_back(std::move(component))
  • 为发布完整的错误信息点赞。不幸的是,双滚动条几乎无法阅读。例如,您可以删除路径
  • @tobi303 感谢您的意见。我添加的内容超出了我的需要,因为我遇到的最后几个问题有人抱怨我没有包含足够的内容。

标签: c++ c++11 vector abstract


【解决方案1】:

下次请将代码简化为错误消息来自的相关部分。剩下的只是噪音。

#include <memory>
#include <vector>

int main()
{
  std::vector<std::unique_ptr<int>> v;
  std::unique_ptr<int> p;
  v.push_back(p);
}

这会尝试将p 的副本插入向量中,这是不允许的,因为您无法复制unique_ptr(它是唯一的)。

您需要移动它而不是复制它,以便所有权从p 转移到向量中的新元素:

  v.push_back(std::move(p));

【讨论】:

  • 公平地说,他可能认为问题出在 ABC,但即便如此,struct ABC{ virtual ~ABC() = 0; }; struct S : ABC{ ~S() {} };std::vector&lt;std::unique_ptr&lt;ABC&gt;&gt; v; std::unique_ptr&lt;ABC&gt; p(new S); 会好很多。
  • 无论哪种方式,将其减少到仍然失败的最小示例将有助于缩小真正的问题所在,并可能帮助他自己调试。
猜你喜欢
  • 2017-11-08
  • 2012-12-03
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
  • 1970-01-01
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
相关资源
最近更新 更多