【问题标题】:pointer to const int using smart pointer使用智能指针指向 const int
【发布时间】:2020-12-04 07:25:04
【问题描述】:

我正在尝试创建一个指向返回为 const int& 的值的智能指针 (unique_ptr),但我的问题可以简单地总结为:

 const int value = 5;
 const int * ptr{nullptr};
 ptr = &value;

这工作,并按预期编译。尝试使用智能指针进行相同操作时:

 const int value = 5;
 std::unique_ptr<const int> ptr{nullptr};
 ptr = &value;

这样我得到编译错误:

no operator "=" matches these operands -- operand types are: std::unique_ptr<const int, std::default_delete<const int>> = const int *

是否可以获得与普通 C 指针相同的行为?

编辑: 我看到我原来的问题太简单了:这是更高级的版本:

int value = 5;
const int& getValue(){
    return value;
};
std::unique_ptr<const int> ptr1{nullptr};
const int * ptr2{nullptr};

ptr1 = std::make_unique<const int>(getValue());
ptr2 = &getValue();
std::cout << "ptr1: " << *ptr1 << "\n";
std::cout << "ptr2: " << *ptr2 << "\n";
value++;
std::cout << "ptr1: " << *ptr1 << "\n";
std::cout << "ptr2: " << *ptr2 << "\n";

打印出来:

ptr1: 5
ptr2: 5

ptr1: 5
ptr2: 6

正如你看到的行为有点不同,现在我相信这是因为make_unique 复制了指向的内存地址中的值

【问题讨论】:

    标签: c++ c++11 smart-pointers unique-ptr


    【解决方案1】:

    std::unique_ptr 是原始指针和内存分配机制的包装器。它更多的是关于内存分配。它旨在自动创建和销毁对象。

    这一行:

    auto ptr = std::make_unique<const int>(5);
    

    相当于:

    auto ptr = new const int{5};
    

    所以在你的行中

    ptr1 = std::make_unique<const int>(getValue());
    

    ptr1 指向一个 const int 类型的新对象,用 getValue() 返回的值初始化。

    而且您不会在程序中更改此值。如果你这样尝试:

    *ptr.get() += 1;
    

    你会得到编译错误,因为 int 是 const。

    【讨论】:

      【解决方案2】:

      std::unique_ptr不能直接用原始指针赋值;你可以使用reset。但是你不应该分配value的地址,(当超出范围时自动销毁),std::unique_ptr会尝试将指针指向delete并导致UB。

      你可能想要

      int value = 5; // we'll constructor a new object, value doens't need to be const
      std::unique_ptr<const int> ptr{nullptr};
      ptr = std::make_unique<const int>(value); // construct a new object and pass the ownership to ptr
      

      编辑

      为了使用smart pointers

      智能指针用于确保在不再使用(引用)对象时将其删除。

      如果您不希望智能指针管理对象,或者不能让智能指针拥有对象,则不应使用智能指针。对于这种特殊情况,我认为使用原始指针就可以了。

      【讨论】:

      • 请注意,value 不再需要为 const
      • 谢谢你,这解决了编译错误,但我用我原来的问题更新了我的问题。
      • @TomasBerger 答案已修改。
      • @TomasBerger 下次重置调用或调用析构函数将尝试指向您提交的delete 指针。如果它不是来自新表达式的指针......那就搞砸了。请注意,unique_ptr 也无法复制。它旨在成为单一所有权点。
      • @TomasBerger 正如 Swift-FridayPie 解释的那样,在这里使用 reset 是个坏主意。
      猜你喜欢
      • 1970-01-01
      • 2015-09-10
      • 1970-01-01
      • 1970-01-01
      • 2019-03-06
      • 1970-01-01
      • 1970-01-01
      • 2021-05-10
      • 1970-01-01
      相关资源
      最近更新 更多