unique_ptr声明后如何赋值?

问题描述 投票:0回答:3
#include <iostream>
#include <memory> // unique_ptr

using namespace std;

int main()
{
    std::unique_ptr<char*> char_ptr;

    char_ptr = (char*)"anisha";
    return 0;
}

我想为代码中其他地方的 unique_ptr 分配一些值。
这会产生以下错误:

char_ptr = (char*)"anisha";

error: no match for ‘operator=’ (operand types are ‘std::unique_ptr<char*>’ and ‘char*’)
     char_ptr = (char*)"anisha";

声明后如何给

unique_ptr
赋值?

c++ pointers smart-pointers unique-ptr
3个回答
4
投票

使用 std::make_unique。 这是对您的代码的编辑 -

#include <iostream>
#include <memory> // unique_ptr

using namespace std;

int main()
{
    std::unique_ptr<char*> char_ptr;

    //char_ptr = (char*)"anisha";
    char_ptr = std::make_unique<char*>((char*)"anisha");
    return 0;
}

2
投票

您不能天真地将指向字符串文字的指针存储在

unique_ptr
中。这里的指针假设它拥有所引用的对象并且可以释放它。但它不能由指针拥有,因为字符串文字具有静态存储持续时间。

如果你想在

unique_ptr
中存储一个可修改的C字符串,你需要分配和复制,你不能用强制类型转换来敲击类型系统并继续你的快乐生活。

因此,将字符串文字转换为唯一指针的实用程序可能如下所示:

template<std::size_t N>
auto literal_dup(char const (&lit)[N]) {
    auto ptr = std::make_unique<char[]>(N);
    std::copy(lit, lit + N, &ptr[0]);
    return ptr; 
}

使用它会看起来像这样:

std::unique_ptr<char[]> c_string;
c_string = literal_dup("anisha");

我们需要使用

unique_ptr
的数组形式来确保它正确地释放缓冲区并且没有未定义的行为。


0
投票

要为

std::unique_ptr
分配新值,请使用
reset()
方法。

但是,关于使用此方法的一个重要注意事项是,当

std::unique_ptr
对象将被销毁时,
Deleter
对象将尝试通过在托管指针上调用
std::unique_ptr
函数来处置托管指针或者当托管指针将被另一个值替换时。

默认的

Deleter
使用托管指针调用
delete
运算符。

话虽这么说,如果

std::unique_ptr
与其默认的
Deleter
一起使用,则使用
std::unique_ptr
方法分配给
reset()
的指针必须指向先前通过调用
new
获得的内存操作员。否则,将导致未定义的行为。

#include <iostream>
#include <memory>

int main()
{
    std::unique_ptr<int> u_ptr;
    
    int * p = new int(100);

    u_ptr.reset(p);
    
    std::cout << *u_ptr << '\n'; // outputs 100

    // u_ptr goes out of scope and calls delete(p); Memory is properly deallocated.
}

但是,可以使用不执行任何操作的

Deleter
函数,在这种情况下,将任何指针的值分配给
std::unique_ptr
都是安全的。但是,在这种情况下,需要注意确保存储在
std::unique_ptr
中的指针不会比它所指向的对象寿命更长。唯一指针的这种用法可能是违反直觉的:

#include <iostream>
#include <memory>

struct fake_deleter
{
    void operator()(int *){}
};


int main()
{
    std::unique_ptr<int, fake_deleter> u_ptr;
    
    int n = 100;

    u_ptr.reset(&n);
    
    std::cout << *u_ptr << '\n'; // outputs 100

    /* u_ptr goes out of scope and calls fake_deleter(&n);
       which does nothing. This is correct in this example */
}
© www.soinside.com 2019 - 2024. All rights reserved.