与临时对象一起使用时了解C ++ std :: shared_ptr [英] Understanding C++ std::shared_ptr when used with temporary objects

查看:285
本文介绍了与临时对象一起使用时了解C ++ std :: shared_ptr的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解 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




  1. 第5行是否使用 p 创建临时表是否正确? shared_ptr (即
    是未命名的 shared_ptr )?

  2. 如果所以为什么 use_count 没有增加。在退出第7行的块之前,temp.object甚至被
    破坏了吗?

  3. 如果它被破坏了,并且 p 的使用计数在块内变为零,
    在退出块后又如何变为1?

  1. Is it correct that line 5, uses p to create a temp. shared_ptr (i.e an unnamed shared_ptr)?
  2. If so why isn't the use_count increased. Is the temp.object destroyed even before we exit the block at line 7.
  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆