C++ Primer 5th edition 以及您的解释在试图解释这个程序时犯了一个常见错误。注意声明:
shared_ptr<int>(q);
创建一个新的临时命名q
,而不是使用q
作为参数创建一个新的临时到 ashared_ptr
的构造函数。下面的示例代码显示了这一点:
#include <iostream>
using namespace std;
struct NAME
{
int p = 0;
NAME()
{
std::cout<<"default constructor"<<std::endl;
}
NAME(int d): p(d)
{
std::cout<<"d: "<<d<<" p: "<<p<<std::endl;
}
NAME(const NAME& n)
{
std::cout<<"const copy constructor"<<std::endl;
}
NAME(NAME& n)
{
std::cout<<"non const copy constructor"<<std::endl;
}
~NAME(){
std::cout<<"destructor: "<<p<<std::endl;
}
};
int main()
{
cout << "Hello World" << endl;
NAME (4);//calls converting constructor
//after the completion of the above full statement the temporary is destroyed and hence you get a destructor call in the output
NAME k;//calls default constructor
std::cout<<"k.p: "<<k.p<<std::endl;
NAME(l);//this creates a temporary named l instead of creating a temporary using l as parameter to NAME's constructor ( in particular,default constructor)
NAME{l};//this creates a temporary using l as parameter to NAME's constructor with non-const copy constructor
return 0;
}
仅当我们使用shared_ptr<int>{q};
代替时,您的解释的第二点才是正确的shared_ptr<int>(q);
。
这表示:
由于作者使用shared_ptr<int>(q);
了一个名为 is created 的局部变量q
,它是一个智能指针,而不是来自外部范围的内置指针。
此局部变量与外部范围q
无关,也与外部范围无关,因此当此局部超出范围时,将调用 shared_ptr 的析构函数。但请注意未释放外部or指向的内存。p
q
q
p
q
所以之后当我们写int foo = *p;
的时候没有未定义的行为。
下面是显示定义本地命名而不是临时使用作为参数的代码。shared_ptr<int>(q);
q
q
#include <iostream>
#include <memory>
using namespace std;
int main()
{
cout << "Hello World" << endl;
shared_ptr<int> p(new int(42)); // reference count is 1
int *q = p.get(); // ok: but don't use q in any way that might delete its pointer
std::cout<<"q's address "<<&q<<std::endl;
std::cout<<"p's address "<<&p<<std::endl;
{ // new block
shared_ptr<int>(q);
std::cout<<"new q's address "<<&q<<std::endl;
std::cout<<"new q's value "<<(*q)<<std::endl;//this produces segmentation fault
} // block ends, local is destroyed
int foo = *p; // this is ok
return 0;
}
在上面的代码中,如果我们尝试访问 localq
的值,*q
那么我们将得到未定义的行为(这可能会使程序/分段错误崩溃),因为我们正在取消引用空指针。如果我们删除它*q
,那么程序就没有未定义的行为。
现在,即使在本书的下一版(第 6 版)中,作者也在使用auto local = shared_ptr<int>(q);
他本可以用来shared_ptr<int>{q};
说明他的观点的时间。