【问题标题】:How does std::make_shared and std::make_unique work behind the scenes? [duplicate]std::make_shared 和 std::make_unique 如何在幕后工作? [复制]
【发布时间】:2021-01-03 10:43:54
【问题描述】:

编辑:我指的是 std::make_shared 和 std::make_shared,而不是它们的实际构造函数。我已经编辑了标题,但下面的文字仍然在谈论构造函数。忽略我使用“构造函数”这个词

我正在尝试了解智能指针如何在幕后工作,但源文件似乎超出了我的理解范围,所以我想也许这里有人可以帮助我。智能指针的构造函数的声明和实现是如何工作的?

通常,您可以像这样创建构造函数:

Object(SomeType member) : member_(member) {}

智能指针显然使用类模板让编码人员选择指针将指向的类型,但构造函数也接受构造指针将指向的类型的对象所需的参数。这是如何实现的?当我们不知道需要多少或什么类型的参数,因为我们不知道我们将要构造的对象的类型时,如何创建这样的构造函数?

Object(/*???*/) : member_(new SomeType(/*???*/)) {}

【问题讨论】:

  • 叫做可变参数模板
  • but the constructor 智能指针只接受一个指针,对象是在智能指针之外构造的。至于来源,见前。 std::make_unique from glibc - 调用 new 是可变参数,调用 std::unique_ptr 获取指针。
  • 我非常推荐 Arthur O'Dwyer 的书《Mastering the C++17 STL》,其中详细讨论了这一点,并给出了一个比默认实现更易于阅读的示例实现。

标签: c++


【解决方案1】:

您可以使用variadic templatesforwarding 将任意数量的参数转发给另一个构造函数或函数。例如:

#include <memory>  // Include std::forward.


template <typename T>
class SmartPointer
{
public:
    template <typename ... Args>
    SmartPointer(Args&& ... args) : the_pointer{new T{std::forward<Args>(args)...}} {}

    // Other methods ...

private:
    T* the_pointer;
};


struct Test
{
    int   a;
    float b;
};

int main()
{
    SmartPointer<Test> pointer { 0, 1.0f };
}

这会将参数01.0f 转发给Test 的构造函数。扩展的类看起来像这样:

class SmartPointer
{
public:
    SmartPointer(int&& a, float&& b) 
        : the_pointer{new Test{std::forward<int&&>(a), std::forward<float&&>(b)}} {}

    // Other methods ...

private:
    Test* the_pointer;
};

Try it online!

【讨论】:

  • 赞成,这应该是公认的答案
  • cppinsights查看模板“扩展”。
【解决方案2】:

这是 C++ 的一个非常强大的特性。它被称为Variadic templates

这是一个使用的简单示例

void print() 
{ 
}
template <typename T, typename... Types> 
void print(T var1, Types... var2) 
{ 
    cout << var1 << endl ; 
  
    print(var2...) ; 
} 

现在您可以使用任意数量的任意类型的变量调用 print。但在一种情况下,传递的类型实现了运算符 &lt;&lt;

那么,你可以这样调用print:

print(1, 2, 3.14, "Pass me any number of arguments", "I will print\n"); 

C++ 标准库非常通用。如果您缺乏对泛型编程的理解,那么理解库源代码可能具有挑战性。一个好的实践练习可以是:实现一个排序函数,一次调用对包含不同类型的多个向量进行排序。

【讨论】:

  • 感谢您的回答!当我尝试在您的示例中运行代码时,我收到一条错误消息,指出在 print 函数的末尾没有用于调用的函数。这是为什么呢?
  • 哦,当然,我的错。让我添加基本情况的功能。谢谢你告诉我。
猜你喜欢
  • 1970-01-01
  • 2023-04-03
  • 2014-04-26
  • 1970-01-01
  • 2014-08-10
  • 2017-05-19
  • 1970-01-01
  • 2021-08-15
  • 1970-01-01
相关资源
最近更新 更多