📜  C++中的随机标头|套装3(分配)(1)

📅  最后修改于: 2023-12-03 15:29:54.885000             🧑  作者: Mango

C++中的随机标头|套装3(分配)

在C++编程中,有一些常用的标头文件,它们提供了许多有用的函数和数据类型,方便程序员进行开发。在这篇文章中,我们将介绍随机标头和分配(allocation)相关的标头文件:<random><memory>

<random>标头文件

在C++中,<random>提供了一些函数和类,可以方便地生成伪随机数。这些随机数生成器使用特定算法和随机数种子生成随机数。

随机数生成器类

<random>提供了几个随机数生成器类,这里我们介绍其中几个:

  • std::linear_congruential_engine:线性同余法生成器
  • std::mersenne_twister_engine:梅森旋转算法生成器
  • std::subtract_with_carry_engine:使用无符号整数加减乘运算来生成随机数

这些类的实例都有一个operator()函数,可以用来生成不同类型的随机数(如整数、浮点数、bool值等)。

分布类

随机数生成器只是生成随机数的工具,如果我们希望在一定范围内生成随机数,那么就可以使用<random>中的分布(distribution)类。

例如,可以使用std::uniform_int_distribution类来生成一个整数分布,它会产生一个指定范围内的均匀分布的随机数。

示例代码:

#include <iostream>
#include <random>

int main()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(1, 6);

    for(int i=0; i<10; i++)
        std::cout << dis(gen) << ' ';

    return 0;
}

输出结果:

4 4 1 4 1 1 4 4 2 2

该示例中,我们使用<random>中的std::mt19937生成器来初始化一个std::uniform_int_distribution整数分布,然后使用函数dis()生成指定范围内的随机数。

<memory>标头文件

在C++编程中,通常使用newdelete来动态地分配、释放内存。然而,手动管理内存可能会导致内存泄漏、段错误等问题。为了避免这些问题,我们可以使用C++的智能指针。

<memory>提供了几种智能指针类型,包括:

  • std::unique_ptr:独占式(unique ownership)指针
  • std::shared_ptr:共享式(shared ownership)指针
  • std::weak_ptr:弱引用指针
std::unique_ptr

std::unique_ptr是C++11标准引入的智能指针,它实现了独占式所有权语义,即同一时间只有一个智能指针可以拥有指针所指向的对象。当对象不再被任何std::unique_ptr持有时,该对象会被自动销毁。

可以使用std::make_unique函数来创建std::unique_ptr对象,示例代码:

#include <iostream>
#include <memory>

int main()
{
    std::unique_ptr<int> ptr = std::make_unique<int>(5);

    std::cout << *ptr << std::endl;

    return 0;
}

输出结果:

5

该示例中,我们使用std::make_unique函数创建一个std::unique_ptr对象,表示一个整数指针。当该std::unique_ptr对象生命周期结束时,它会自动释放指针指向的内存。

std::shared_ptr

std::shared_ptr是一个允许多个智能指针共享同一个对象的智能指针。它具有引用计数和自动内存管理功能。当std::shared_ptr对象的引用计数为0时,即没有任何智能指针再指向该对象时,对象会被自动销毁。

可以使用std::make_shared函数来创建std::shared_ptr对象,示例代码:

#include <iostream>
#include <memory>

int main()
{
    std::shared_ptr<int> ptr1 = std::make_shared<int>(5);
    std::shared_ptr<int> ptr2 = ptr1;

    std::cout << *ptr1 << std::endl;
    std::cout << *ptr2 << std::endl;

    return 0;
}

输出结果:

5
5

该示例中,我们使用std::make_shared函数创建一个std::shared_ptr对象,表示一个整数指针。然后,我们又创建了一个新的std::shared_ptr对象,并将其指向与ptr1相同的内存地址。因此,ptr1和ptr2都指向同一个对象。当引用计数为0时,该对象会被自动销毁。

std::weak_ptr

std::weak_ptr是指向std::shared_ptr指针的弱引用。它不会增加对象的引用计数,而且可以检查所指向的对象是否已被释放。

通常情况下,我们使用std::shared_ptr来管理对象的生命周期,如果需要检查对象是否已被释放,可以将其转换为std::weak_ptr来实现。示例代码:

#include <iostream>
#include <memory>

int main()
{
    std::shared_ptr<int> s_ptr = std::make_shared<int>(5);
    std::weak_ptr<int> w_ptr = s_ptr;

    if(!w_ptr.expired())
        std::cout << *w_ptr.lock() << std::endl;

    s_ptr.reset();

    if(w_ptr.expired())
        std::cout << "expired" << std::endl;

    return 0;
}

输出结果:

5
expired

该示例中,我们首先创建了一个std::shared_ptr智能指针和一个弱引用std::weak_ptr,它们都指向同一个对象。接着,我们使用方法w_ptr.expired()检查对象是否已经被销毁。如果对象未被销毁,我们可以使用方法w_ptr.lock()将其转换为std::shared_ptr智能指针来访问该对象。然后我们调用s_ptr.reset()释放std::shared_ptr对象,接着再次检查对象是否已被销毁,此时std::weak_ptr的方法expired()返回true。