当前位置: 首页 > 知识库问答 >
问题:

C++STD::UNIQUE_PTR但不可移动?

韩志专
2023-03-14

我正在使用STD::UNIQUE_PTR在类上创建一些公共成员,这些成员必须是不可复制或可移动的。但是STD::UNIQUE_PTR是可移动的,我想知道如果有人移动STD::UNIQUE_PTR包含的指针,然后我尝试访问被移动的那个类的STD::UNIQUE_PTR成员,会发生什么。

#include <cstdlib>
#include <memory>
#include <string>
#include <iostream>

struct obj
{
    obj(std::string id)
        : id(id)
    {

    }

    void identif()
    {
        std::cout << "i am " << id << std::endl;
    }

    std::string id;
};

struct objs
{
    // They must stay here no mater what.
    std::unique_ptr< obj > obj_a;
    std::unique_ptr< obj > obj_b;
    std::unique_ptr< obj > obj_c;

    objs()
        : obj_a(std::unique_ptr< obj >( new obj("object a") ))
            ,obj_b(std::unique_ptr< obj >( new obj("object b") ))
            ,obj_c(std::unique_ptr< obj >( new obj("object c") ))
    {

    }

    void do_a()
    {
        std::cout << " member: " << obj_a->id << std::endl;
        std::cout << " method: ";
        obj_a->identif();
    }

    void do_b()
    {
        std::cout << " member: " << obj_b->id << std::endl;
        std::cout << " method: ";
        obj_b->identif();
    }

    void do_c()
    {
        std::cout << " member: " << obj_c->id << std::endl;
        std::cout << " method: ";
        obj_c->identif();
    }
};

int main(int argc, char** argv)
{

    objs obx;

    std::cout << " before move: " << std::endl;

    obx.do_a();
    obx.do_b();
    obx.do_c();

    std::cout << " after move: " << std::endl;

    std::unique_ptr< obj > newb(std::move(obx.obj_b));

    obx.do_a();
    obx.do_b();
    obx.do_c();

    return EXIT_SUCCESS;
}

我所需要的就是使std::unique_ptr不可移动,并简单地保存一个唯一的指针,该指针不能从拥有它的类中移动或复制。

实际的代码是Nano-signal-slot库中的nano::signal类。(以防有人需要实际代码)

编辑:适应使用内文的方法,并使其工作。我发布代码是因为Nevin在容器上而不是对象上实现了它。

#include <cstdlib>
#include <memory>
#include <string>
#include <iostream>

struct obj
{
    obj(std::string id)
        : id(id)
    {

    }

    obj(obj const&) = delete;
    obj& operator=(obj const&) = delete;
    obj& operator=(obj&&) = delete;
    obj(obj&&) = delete;


    void identif()
    {
        std::cout << "i am " << id << std::endl;
    }

    std::string id;
};

struct objs
{
    const std::unique_ptr< obj > obj_a;
    const std::unique_ptr< obj > obj_b;
    const std::unique_ptr< obj > obj_c;

    objs()
        : obj_a(std::unique_ptr< obj >( new obj("object a") ))
            ,obj_b(std::unique_ptr< obj >( new obj("object b") ))
            ,obj_c(std::unique_ptr< obj >( new obj("object c") ))
    {

    }

    void do_a()
    {
        std::cout << " member: " << obj_a->id << std::endl;
        std::cout << " method: ";
        obj_a->identif();
    }

    void do_b()
    {
        std::cout << " member: " << obj_b->id << std::endl;
        std::cout << " method: ";
        obj_b->identif();
    }

    void do_c()
    {
        std::cout << " member: " << obj_c->id << std::endl;
        std::cout << " method: ";
        obj_c->identif();
    }
};

int main(int argc, char** argv)
{

    objs obx;

    std::cout << " before move: " << std::endl;

    obx.do_a();
    obx.do_b();
    obx.do_c();

    std::cout << " after move: " << std::endl;

    std::unique_ptr< obj > newb(std::move(obx.obj_b));

    obx.do_a();
    obx.do_b();
    obx.do_c();

    return EXIT_SUCCESS;
}
main.cpp: In function 'int main(int, char**)':
main.cpp:77:53: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = obj; _Dp = std::default_delete<obj>]'
     std::unique_ptr< obj > newb(std::move(obx.obj_b));
                                                     ^
In file included from /usr/include/c++/4.8/memory:81:0,
                 from main.cpp:2:
/usr/include/c++/4.8/bits/unique_ptr.h:273:7: error: declared here
       unique_ptr(const unique_ptr&) = delete;
       ^

共有1个答案

汪庆
2023-03-14

只需使objs不可复制和不可移动,如下所示:

struct objs
{
    objs(objs const&) = delete;
    objs& operator=(objs const&) = delete;
    objs& operator=(objs&&) = delete;
    objs(objs&&) = delete;

    std::unique_ptr< obj > obj_a;
    std::unique_ptr< obj > obj_b;
    std::unique_ptr< obj > obj_c;

    objs()
        : obj_a(std::unique_ptr< obj >( new obj("object a") ))
            ,obj_b(std::unique_ptr< obj >( new obj("object b") ))
            ,obj_c(std::unique_ptr< obj >( new obj("object c") ))
        {}

};

此外,一旦您完成了这一点,内部也不需要指针。您可以将代码简化为:

struct objs
{
    objs(objs const&) = delete;
    objs& operator=(objs const&) = delete;
    objs& operator=(objs&&) = delete;
    objs(objs&&) = delete;

    obj obj_a;
    obj obj_b;
    obj obj_c;

    objs()
        : obj_a("object a")
            ,obj_b("object b")
            ,obj_c("object c")
            {}

};
 类似资料:
  • 代码如下: 我假设错误发生在insert函数中,并且与参数初始化有关。 bintree.cpp:65:27:错误:使用删除的函数'std::unique_ptr<_tp,_dp>::unique_ptr(const std::unique_ptr<_tp,_dp>&)[with_tp=bintreenode;_dp=std::default_delete>]“tree.insert(tree.ro

  • 问题内容: 我对boost.python相当陌生,并试图将函数的返回值公开给python。 函数签名如下所示: 在python中调用函数时,出现以下错误: 我在python中的函数调用如下所示: 我试图公开std :: unique_ptr,但无法使其正常工作。有人知道如何正确公开指针类吗?谢谢! 编辑: 我尝试以下操作: 这个例子可以编译,但是我仍然得到上面提到的错误。另外,我试图公开类本身 问

  • 为啥unique_ptr的移动比shared_ptr赋值要慢? 在Modern Effective C++中,提倡使用unique_ptr代替裸指针,因为unique_ptr的大小和性能与裸指针基本一致但更安全,而shared_ptr由于由原子变量的存在性能更差,但是同步赋值试下来,unique_ptr的移动很慢。 运行结果:

  • 我正在使用Visual Studio 2012。我有一张如下所示的地图: 我试图插入这样的数据: 我在编译时遇到了以下错误: microsoft visual studio 11.0\vc\include\utility(182): error C2248: 'std::unique_ptr 我也试过用make_pair插入数据,也有同样的问题。我错过了什么?我已经试着解决这个问题两个小时了,但是

  • 当一个包含不可移动的内容时,我不知道如何完美地转发它。

  • 我有一个类实例的向量。这些实例中的每一个都有一个指向另一个类的unique_ptr。由于我从来不尝试复制类实例,甚至不尝试共享指针,所以我觉得unique_ptr比shared_ptrs更合适,因为指针不是共享的,而是只能通过类实例访问。 这是不好的练习吗?为什么这行不通?我知道将一个实例复制到一个唯一的指针将是错误的,但是既然我移动了它,我不明白为什么不允许这样做? 我必须创建一个自定义移动构造