我是指针新手,所以请考虑以下代码
#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);
此行创建一个 new 指针,其中包含 xSmart 在调用时的值。 它不会创建指向现有变量的指针。
您不想使用
std::unique_ptr::reset
。
std::unique_ptr<bar> pointer;
pointer.reset(&xSmart);
因为它会在销毁时删除本地的某些内容,正如所引用的答案所说。您不希望在自动(堆叠)对象周围使用
std::unique_ptr
或 std::shared_ptr
。
std::make_unique<double>(xSmart)
的作用:
sizeof(double)
并将给定的 value 分配给它,就像调用 new double{xSmart}
一样。std::unique_ptr<double>
。智能指针在其析构函数中,一旦超出范围,就会 delete
分配的内存。std::unique_ptr
应该永远不指向堆内存,如std::unique_ptr<double>{&xSmart}
中所示,因为稍后尝试delete
会导致崩溃和/或任意未定义的行为。综上所述,
xSmart
指针中没有对pSmart
的引用。 xSmart
中的值已复制到新的动态分配的 double
。下面是一些例子,有好有坏。
nullptr
。Deleter
类可以提供给std::unique_ptr
。这就是我们在这里所做的。删除器“什么也不做”。这样,您就可以构造一个“智能”(实际上是简化)指针,该指针指向堆位置并且不会造成严重破坏。不用说,这充其量是完全无用且令人困惑的。
这大致基于您的动态智能指针情况。首先我们动态分配一个 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 smart 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 &rUselessSmart{*pUselessSmart};
rUselessSmart = 10;
std::cout
<< "value of variable we are pointing to through a smart pointer is : "
<< *pUselessSmart << std::endl;
}