与临时对象一起使用时了解C ++ std :: shared_ptr [英] Understanding C++ std::shared_ptr when used with temporary objects
问题描述
我试图了解 shared_ptr p
在用于构建未命名 shared_ptr
及其对 p
的影响。我正在玩自己的示例,并编写了以下代码:
I am trying to understand the use of a shared_ptr p
when it is used in the construction of an unnamed shared_ptr
and the effects this has on p
. I was toying with my own examples and wrote the following piece of code:
shared_ptr<int> p(new int(42));
cout << p.use_count() << '\n';
{
cout << p.use_count() << '\n';
shared_ptr<int>(p);
cout << p.use_count() << '\n';
}
cout << p.use_count() << '\n';
Output:
1
1
0
1
- 第5行是否使用
p
创建临时表是否正确?shared_ptr
(即
是未命名的shared_ptr
)? - 如果所以为什么
use_count
没有增加。在退出第7行的块之前,temp.object甚至被
破坏了吗? - 如果它被破坏了,并且
p
的使用计数在块内变为零,
在退出块后又如何变为1?
- Is it correct that line 5, uses
p
to create a temp.shared_ptr
(i.e an unnamedshared_ptr
)? - If so why isn't the
use_count
increased. Is the temp.object destroyed even before we exit the block at line 7. - If it is destroyed and
p
's use count becomes zero inside the block, how come it is 1 again after we exit the block?
如果我要使用命名为 shared_ptr
第5行的q
,即:
If I would have used a named shared_ptr
q
on line 5, i.e:
shared_ptr<int>q(p);
一切都会按预期进行,在第5行之后的块中,
的使用计数为2,并在退出该块后再次变为1。
Everything would work as expected, inside the block after line 5 the use count would be 2 and after we exit the block it would be 1 again.
推荐答案
根据C ++标准(8.5.1.3显式类型转换(功能符号)
According to the C++ Standard (8.5.1.3 Explicit type conversion (functional notation))
1一个简单类型说明符(10.1.7.2)或类型名称说明符(17.7)
后跟一个带括号的可选表达式列表或
braced-init-list(初始化程序),构造一个指定的
类型的值(给定初始值设定项...
1 A simple-type-specifier (10.1.7.2) or typename-specifier (17.7) followed by a parenthesized optional expressionlist or by a braced-init-list (the initializer) constructs a value of the specified type given the initializer...
因此此表达式语句中的表达式
So the expression in this expression statement
shared_ptr<int>(p);
看起来像是显式类型转换(函数)表达式。
looks like an explicit type conversion (functional) expression.
另一方面,声明中的声明符可以放在括号中。例如
On the other hand, a declarator in a declaration can be enclosed in parentheses. For example
int ( x );
是有效的声明。
所以此语句
shared_ptr<int>(p);
可以解释为声明,例如
shared_ptr<int> ( p );
因此存在歧义。
C ++标准通过以下方式(9.8模糊度分辨率)解决了这种歧义
The C++ Standard resolves this ambiguity the following way (9.8 Ambiguity resolution)
1语法中包含表达式语句
和声明有歧义:具有函数式
显式类型转换(8.5.1.3)的表达式语句,因为其最左边的子表达式可以是
与第一个声明符
以(开头的声明)不可区分。在这种情况下,声明是声明。
因此此语句在内部代码块中
Thus this statement in the inner code block
shared_ptr<int>(p);
是新共享指针的声明,其名称为 p
隐藏外部代码块中同名 p
的对象的先前声明,并使用默认构造函数创建该声明
is a declaration of a new shared pointer with the name p
that hides the previous declaration of the object with the same name p
in the outer code block and that is created by using the defalut constructor
constexpr shared_ptr() noexcept;
根据该构造函数的描述
2效果:构造一个空的shared_ptr对象。
2 Effects: Constructs an empty shared_ptr object.
3个后置条件: use_count()== 0 && get()== nullptr。
3 Postconditions: use_count() == 0 && get() == nullptr.
如果您要处理表达式而不是声明,那么您要做的就是将表达式的主体括在括号中,以将表达式作为主要表达式。
If you want to deal with an expression instead of the declaration then all you need to do is to enclose the body of the statement in parentheses getting a primary expression in an expression statement.
这里是一个演示程序。
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> p( new int( 42 ) );
std::cout << "#1: " << p.use_count() << '\n';
{
std::cout << "#2: " << p.use_count() << '\n';
( std::shared_ptr<int>( p ) );
std::cout << "#3: " << p.use_count() << '\n';
}
std::cout << "#4: " << p.use_count() << '\n';
return 0;
}
在这种情况下,其输出为
In this case its output is
#1: 1
#2: 1
#3: 1
#4: 1
这篇关于与临时对象一起使用时了解C ++ std :: shared_ptr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!