#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
赋值?
使用 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;
}
您不能天真地将指向字符串文字的指针存储在
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
的数组形式来确保它正确地释放缓冲区并且没有未定义的行为。
要为
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 */
}