【问题标题】:How to understand `std::make_shared<Object>("foo")`?如何理解`std::make_shared<Object>("foo")`?
【发布时间】:2020-09-10 21:32:47
【问题描述】:

std::make_shared&lt;Object&gt;("foo") 是做什么的?

std::shared_ptr<Object> p1 = std::make_shared<Object>("foo");

我知道std::make_shared&lt;T&gt; 是模板类,我可以理解Object("foo") 确实是一个临时对象。但是我看不懂std::make_shared&lt;Object&gt;("foo")

有人可以一步一步地解释我创建的对象序列和它完成的操作吗?

【问题讨论】:

  • std::make_shared&lt;T&gt;() 不是模板类。它是一个辅助函数,它 (1) 动态分配一个 T,它使用提供的参数(任何参数 - 其中可能有零个或多个 - 在 () 之间)和 (2) 构造和返回一个std::shared_ptr&lt;T&gt; 来管理该对象。
  • std::make_shared&lt;T&gt;()不是模板函数吗?
  • 是的,它是一个模板函数。您将其描述为模板类,但事实并非如此。
  • 我明白了,很抱歉打扰您。我会尽量避免。
  • @john 我认为您的 cmets 很有帮助。您是刚刚删除了它们吗?还是仅仅因为我们有相似的名字?

标签: c++ template-classes


【解决方案1】:

std::make_shared 是模板函数,不是模板类。

函数的模板参数指定要创建的类型。

函数的参数按原样传递给该类型的构造函数。

该函数返回一个std::shared_ptr,其中包含一个指向所创建类型的指针。

因此,std::make_shared&lt;Object&gt;("foo") 动态地创建一个由"foo" 构造的Object 实例,并返回一个包含指向该实例的指针的std::shared_ptr&lt;Object&gt;

这等价于以下内容(但不完全相同,因为幕后涉及额外的优化):

std::shared_ptr<Object> p1(new Object("foo"));

【讨论】:

  • 能告诉我在哪里可以找到相关的源代码吗?
  • 从头文件&lt;memory&gt;开始,尽管代码可能位于也可能不在该文件中。
  • @john 顺便说一句,std::make_shared&lt;T&gt;() 不是模板函数吗?彼得说它是一个辅助函数。我很困惑。
  • 既是模板函数又是辅助函数。辅助函数不是官方的 C++ 术语。
【解决方案2】:
std::make_shared<Object>("foo")

方法

请注意此代码开头的 std::make_shared。它标识了一个功能。如果我们把实际的函数放在一边,往后退一步,那么在 符号和 () 符号之前你有一个函数名。

通用

此代码中的 指定在这种情况下将泛型 T 指定为 Object。将其视为临时对象并不是一个好主意。这是一个规范。

通话

("foo") 确保调用函数并将参数传递给它。

底线

documentation 为您提供了正确的描述:

它告诉您指定类型的构造函数(在本例中为 Object)将被实例化,并将被包装在 shared_ptr 中。

【讨论】:

  • 我会听从你的建议。正如您所说:“在此代码中指定通用 T 在这种情况下指定为 Object。将其视为临时对象并不是一个好主意。它是一个规范。”,又提出了一个问题: “这是一个规范。”是什么意思?
  • @John 它基本上意味着就此处使用的泛型而言,&lt;T&gt; 表示“某种类型”,通常用于确保您可以在不同的用例中重用相同的代码.在这里,特别是,您现在可能想要创建 Object 的 shared_ptr,但稍后您可能会使用不同的类型。在实现make_shared 时,实现它的人无法提前告诉您您将需要一个对象的shared_ptr。他们对此不可知,并决定支持任何类型。这是泛型背后的基本思想。
  • @John 在这里,&lt;Object&gt; 部分指定T 在这种情况下是Object。很高兴函数本身使用泛型类型并支持任何类型,但是在您的特定情况下,类型是已知的并且需要指定。
  • 我明白了。谢谢你的澄清。我同意@Remy Lebeau 的观点,std::make_shared&lt;T&gt; 是一个模板函数。但彼得说它是一个辅助函数。你怎么看?非常感谢。
  • @John 两者兼而有之。这是一个模板函数,因为它使用&lt;T&gt; 的泛型作为模板。它也是一个辅助函数,因为 if 执行函数的部分计算。
猜你喜欢
  • 2021-08-15
  • 2013-08-20
  • 1970-01-01
  • 2014-04-26
  • 1970-01-01
  • 2021-06-05
  • 2020-01-20
  • 2014-08-10
相关资源
最近更新 更多