提问人:Novice_Developer 提问时间:11/15/2023 最后编辑:Remy LebeauNovice_Developer 更新时间:11/16/2023 访问量:117
等效于智能指针中的指针
Equivalent of pointer in smart pointers
问:
我是指针的新手,所以请考虑以下代码:
#include <iostream>
#include <memory>
int main()
{
double xNormal{5};
double * pNormal = &xNormal;
xNormal = 10;
std::cout<<"value of variable we are pointing to is : "<<*pNormal<<std::endl;
double xSmart{5};
std::unique_ptr<double> pSmart = std::make_unique<double>(xSmart);
xSmart = 10;
std::cout<<"value of variable we are pointing to through a smart pointer is : "<<*pSmart<<std::endl;
}
此代码的输出为:
value of variable we are pointing to is : 10
value of variable we are pointing to through a smart pointer is : 5
在此代码中,如果我们使用普通指针并更改原始变量的值,则取消引用的指针也会“跟踪”该值,因为它指向该内存位置。
当谈到智能指针时,我注意到没有这样的“跟踪”,也许我在理解上犯了错误,但问题是,智能指针中的等价物是什么?double * pNormal = &xNormal;
答:
std::unique_ptr<double> pSmart = std::make_unique<double>(xSmart);
此行创建一个新指针,其中包含调用时的值。它不会创建指向现有变量的指针。xSmart
您不想使用 .std::unique_ptr::reset()
std::unique_ptr<bar> pointer;
pointer.reset(&xSmart);
因为它会破坏一些局部的东西,正如提到的答案所说。您不想要或绕过自动(堆叠)对象。delete
std::unique_ptr
std::shared_ptr
评论
std::unique_ptr::reset
delete
release()
有什么作用:std::make_unique<double>(xSmart)
- 分配堆内存并为其分配给定值,就像调用 一样。
sizeof(double)
new double{xSmart}
- 返回指向新内存的指向。智能指针在其析构函数中,一旦超出范围,就会分配内存。
std::unique_ptr<double>
delete
- 因此,a 永远不应该指向堆内存,就像 一样,因为它稍后尝试 a 会导致崩溃和/或任意未定义的行为。
std::unique_ptr
std::unique_ptr<double>{&xSmart}
delete
总之,指针中没有引用。的值 from 已复制到新的、动态分配的 .以下是一些好有坏的例子。xSmart
pSmart
xSmart
double
- 只是一个风格建议/意见:更喜欢引用而不是指针,这些指针总是指向存在的东西,即不应该持有.
nullptr
- 不要在家尝试这个。在文档中,您可以发现自定义类可以提供给 .这就是我们在这里所做的。删除程序不执行任何操作。这样一来,你就可以构造一个“智能”(实际上是愚蠢的)指针,它指向堆位置,并且不会造成严重破坏。毋庸置疑,这充其量是完全无用和令人困惑的。
Deleter
std::unique_ptr
- 这大致基于您的动态、智能指针大小写。首先,我们动态分配并分配给它。然后,我们采用一个老式的指针指向 .然后我们通过指针分配它,并检查指向的位置(在堆上)是否真的发生了变化。是的,它做到了。这次我们使用 ,即模板的默认值,即 end 和 析构函数运行时分配的堆内存。
double
5
double
std::default_delete<double>
Deleter
delete
main()
pUselessSmart
#include <iostream>
#include <memory>
int main() {
// Example 0: A local reference to a double on the stack.
double xNormal{5};
double &rNormal{xNormal};
xNormal = 10;
std::cout << "value of variable we are pointing to is : " << rNormal
<< std::endl;
// Example 1: A “smart” pointer pointing at a double on the stack.
double xSmart{5};
std::unique_ptr<double, void (*)(double *)> pSmart{&xSmart, +[](double *) {}};
xSmart = 10;
std::cout
<< "value of variable we are pointing to through a dumb pointer is : "
<< *pSmart << std::endl;
// Example 2: A smart pointer pointing at a heap-allocated double.
std::unique_ptr<double> pUselessSmart{std::make_unique<double>(5)};
double *qUselessSmart{pUselessSmart.get()};
*qUselessSmart = 10;
std::cout
<< "value of variable we are pointing to through a smart pointer is : "
<< *pUselessSmart << std::endl;
}
我上面愚蠢的“智能”指针示例的一个关键缺陷是代码可读性差。按照惯例,a 表示内存所有权。它可以将所有权转移到其他实例,可能通过 s 和调用站点,使用 R-value() 引用和相应的复制构造函数并获取引用(与对应的 d)。但是,一个不应该指向它不拥有的东西,即它不能/不应该的东西,例如堆栈内存、另一个人拥有的内存(这与它的名字相悖)等。std::unique_ptr
return
&&
operator =()
&&
const &
= delete
std::unique_ptr
delete
std::unique_ptr
unique
上一个:从多维数组中的 mid 调用数组
下一个:无法打印的字符指针 [重复]
评论
std::endl
'\n'
std::unique_ptr<double> pSmart(&xSmart);
pSmart
xSmart
pSmart.release()
std::make_unique<double>(xSmart)
xSmart
double
xSmart
xSmart
double xSmart{5}; double * pSmart = new double{xSmart}; xSmart = 10; std::cout << *pSmart; delete pSmart;
&xSmart
pSmart
*pSmart = 10;