简介

  • C++中常用到的类

std::enable_shared_from_this

在 C++ 中,std::enable_shared_from_this 是一个模板类,位于 <memory> 头文件中,它用于在共享所有权的智能指针(std::shared_ptr)对象中获取指向该对象的 std::shared_ptr

当一个类继承自 std::enable_shared_from_this 并且其对象被一个 std::shared_ptr 管理时,可以使用 shared_from_this() 成员函数来获取一个指向当前对象的 std::shared_ptr

以下是 std::enable_shared_from_this 的一些重要特点和使用方法:

  1. 必须使用 std::shared_ptr 管理对象std::enable_shared_from_this 只能与 std::shared_ptr 一起使用。使用其他类型的智能指针或裸指针将导致未定义行为。

  2. 继承 std::enable_shared_from_this:要使用 std::enable_shared_from_this,你的类必须继承自它,例如:
    1
    2
    3
    
    class MyClass : public std::enable_shared_from_this<MyClass> {
      // ...
    };
    
  3. 获取 std::shared_ptr 的方法:通过调用 shared_from_this() 成员函数,可以获取指向当前对象的 std::shared_ptr,例如:
    1
    
    std::shared_ptr<MyClass> ptr = obj.shared_from_this();
    
  4. 注意事项
    • shared_from_this() 只能在由 std::shared_ptr 管理的对象中调用。在构造函数期间或通过裸指针调用会导致未定义行为。
    • 必须先创建 std::shared_ptr 对象,然后才能调用 shared_from_this()。否则,将返回一个空的 std::shared_ptr

使用 std::enable_shared_from_this 可以方便地获取指向当前对象的 std::shared_ptr,以便与其他共享该对象所有权的智能指针一起使用。这在实现资源共享和对象生命周期管理时非常有用,特别是在涉及对象自引用的情况下。

std::thread

std::thread是C++标准库提供的用于创建和管理线程的类。它位于<thread>头文件中,并定义在std命名空间中。

std::thread类提供了以下主要功能和成员函数:

  1. 构造函数:
    • explicit thread() noexcept;
    • template <class Function, class... Args> explicit thread(Function&& f, Args&&... args);
    • thread(const thread&) = delete;(复制构造函数被禁用)
    • thread(thread&& other) noexcept;(移动构造函数)
  2. 成员函数:
    • operator=: 赋值运算符,用于将一个线程对象赋值给另一个线程对象。
    • join(): 阻塞调用线程,直到该线程执行完成。
    • detach(): 将线程分离,使其在后台运行,不再与调用线程同步。
    • swap(): 交换两个线程对象的内容。
    • get_id(): 返回线程的唯一标识符。
    • joinable(): 检查线程是否可加入或分离。
    • native_handle(): 返回底层操作系统的线程句柄。
    • hardware_concurrency(): 返回支持并发执行的线程数量。
  3. 静态成员函数:
    • std::thread::id: 表示线程的唯一标识符的类型。
    • std::thread::native_handle_type: 表示底层操作系统线程句柄的类型。
    • std::thread::hardware_concurrency(): 返回支持并发执行的线程数量。

使用std::thread类创建线程的一般步骤如下:

  1. 定义一个可调用的函数或函数对象,作为线程的执行逻辑。
  2. 创建std::thread对象,并将可调用的函数或函数对象作为参数传递给构造函数。
  3. 通过调用join()等待线程执行完成,或使用detach()分离线程并允许其在后台运行。

以下是一个简单的示例,演示如何使用std::thread类创建和管理线程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <thread>

// 可调用的函数作为线程执行逻辑
void threadFunction(int id) {
    std::cout << "Thread " << id << " started." << std::endl;
    // 执行一些任务
    std::cout << "Thread " << id << " finished." << std::endl;
}

int main() {
    // 创建线程对象,并指定可调用的函数及其参数
    std::thread t1(threadFunction, 1);
    std::thread t2(threadFunction, 2);

    // 等待线程执行完成
    t1.join();
    t2.join();

    return 0;
}

注意,使用std::thread类创建线程时,需要确保线程的执行完成或分离,否则会导致程序异常退出或资源泄漏。

这是对std::thread类的简要解释,您可以查阅C++标准库的文档以获取更详细的信息和用法示例。


std::fstream

std::fstream 是 C++ 标准库中用于文件输入输出的类,它是 std::ifstream(文件输入流)和 std::ofstream(文件输出流)的基类,并结合了它们的功能,使得在同一个对象中可以实现文件的读取和写入。

要使用 std::fstream 类,需要包含 <fstream> 头文件。

下面是 std::fstream 类的详细解释:

构造函数:

  • explicit fstream(const char* filename, ios_base::openmode mode = ios_base::in | ios_base::out);
  • explicit fstream(const std::string& filename, ios_base::openmode mode = ios_base::in | ios_base::out);

构造函数用于创建 std::fstream 对象并打开文件。参数 filename 是要打开的文件名,参数 mode 是打开文件的模式,可以使用 ios_base::in 表示读取模式,ios_base::out 表示写入模式,ios_base::app 表示追加写入模式等等。

成员函数:

  • void open(const char* filename, ios_base::openmode mode = ios_base::in | ios_base::out);
  • void open(const std::string& filename, ios_base::openmode mode = ios_base::in | ios_base::out);

open 函数用于打开一个新的文件,并可以指定打开模式。

  • void close();

close 函数用于关闭文件。

  • bool is_open() const;

is_open 函数用于检查文件是否成功打开,返回 true 表示文件已经成功打开,false 表示文件未打开或者打开失败。

  • void clear();

clear 函数用于清除错误状态和结束-of-file标志。

  • void seekg(std::streampos pos);
  • void seekg(std::streamoff off, std::ios_base::seekdir way);

seekg 函数用于设置输入位置指针的位置。第一种重载接受一个绝对位置 pos,第二种重载接受一个相对位置 off 和一个方向 way,方向可以是 std::ios_base::beg(从开头计算位置),std::ios_base::cur(从当前位置计算位置),或者 std::ios_base::end(从文件末尾计算位置)。

  • std::streampos tellg();

tellg 函数用于获取当前输入位置指针的位置。

  • void seekp(std::streampos pos);
  • void seekp(std::streamoff off, std::ios_base::seekdir way);

seekp 函数用于设置输出位置指针的位置,用法与 seekg 类似。

  • std::streampos tellp();

tellp 函数用于获取当前输出位置指针的位置。

  • std::fstream& operator<<(T val);
  • std::fstream& operator>>(T& val);

这些重载的运算符用于将数据写入文件(operator<<)或从文件读取数据(operator>>)。T 是要写入或读取的数据类型。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <fstream>

int main() {
    std::fstream file("example.txt", std::ios::out | std::ios::in); // 打开文件用于读写
    if (file.is_open()) {
        file << "Hello, World!\n"; // 写入数据到文件
        file.seekg(0); // 定位输入位置指针到文件开头
        std::string line;
        std::getline(file, line); // 从文件读取一行数据
        std::cout << "Data read from file: " << line << std::endl;
        file.close(); // 关闭文件
    } else {
        std::cout << "Failed to open file!" << std::endl;
    }
    return 0;
}

std::fstream 类提供了一个灵活而强大的接口来处理文件的读写操作。通过合理使用其成员函数和运算符重载,可以方便地在 C++ 程序中进行文件输入输出的操作。


std::ifstream

std::ifstream 是 C++ 标准库中用于文件输入的类,用于从文件中读取数据。它是基于流的输入操作符 >> 实现的,可以通过打开文件并使用 >> 运算符将文件中的数据读取到不同类型的变量中。

以下是 std::ifstream 类的一些常用方法和功能:

  1. 打开文件:可以使用 open() 方法打开文件,指定要读取的文件路径和打开模式。打开模式可以是 std::ios::in(默认)或其他可选模式,如 std::ios::binarystd::ios::ate 等。

  2. 关闭文件:使用 close() 方法关闭打开的文件。在读取完文件内容后,应该显式地关闭文件。

  3. 读取数据:使用 >> 运算符可以将文件中的数据读取到不同类型的变量中。例如,可以使用 >> 运算符读取整数、浮点数、字符串等数据。

  4. 检查文件状态:可以使用 good()eof()fail()bad() 等方法检查文件的状态。例如,good() 方法用于检查文件是否处于可读取状态,eof() 方法用于检查是否已到达文件末尾,fail() 方法用于检查读取操作是否失败。

  5. 定位文件指针:可以使用 seekg() 方法定位文件指针到指定位置,从而实现随机读取文件内容。

  6. 获取文件大小:可以结合文件指针定位和 tellg() 方法获取文件的大小。

  7. 检查文件是否打开:使用 is_open() 方法可以检查文件是否成功打开。

  8. 逐行读取文件:可以使用 getline() 方法逐行读取文件内容。

使用 std::ifstream 类可以方便地打开、读取和处理文件内容。在使用完毕后,应该关闭文件以释放资源。


std::ofstream

std::ofstream 是 C++ 标准库中用于文件输出的类,用于将数据写入文件中。它是基于流的输出操作符 << 实现的,可以通过打开文件并使用 << 运算符将数据写入文件。

以下是 std::ofstream 类的一些常用方法和功能:

  1. 打开文件:可以使用 open() 方法打开文件,指定要写入的文件路径和打开模式。打开模式可以是 std::ios::out(默认)或其他可选模式,如 std::ios::binarystd::ios::app 等。

  2. 关闭文件:使用 close() 方法关闭打开的文件。在写入完文件内容后,应该显式地关闭文件。

  3. 写入数据:使用 << 运算符可以将数据写入文件。例如,可以使用 << 运算符将整数、浮点数、字符串等数据写入文件。

  4. 检查文件状态:可以使用 good()fail()bad() 方法检查文件的状态。例如,good() 方法用于检查文件是否处于可写入状态,fail() 方法用于检查写入操作是否失败。

  5. 定位文件指针:可以使用 seekp() 方法定位文件指针到指定位置,从而实现随机写入文件内容。

  6. 检查文件是否打开:使用 is_open() 方法可以检查文件是否成功打开。


使用 std::ofstream 类可以方便地打开文件并将数据写入文件。在使用完毕后,应该关闭文件以释放资源。

  • std::ofstream是C++标准库提供的一个输出文件流类,用于将数据写入到文件中。它是std::ostream的派生类,继承了std::ostream中的输出操作符<<,可以方便地向文件写入各种类型的数据。

  • 使用std::ofstream需要包含头文件<fstream>,并通过构造函数创建一个输出文件流对象,可以指定要打开的文件名和打开模式。常用的打开模式包括:
    • std::ios::out:以写入模式打开文件。
    • std::ios::app:在文件末尾追加内容。
    • std::ios::trunc:如果文件存在,删除文件内容并重新创建。
    • std::ios::binary:以二进制模式打开文件。
  • 下面是一个示例代码,演示如何使用std::ofstream写入数据到文件:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    #include <iostream>
    #include <fstream>
    
    int main() {
        std::string filename = "example.txt"; // 文件名
    
        // 创建输出文件流对象并打开文件
        std::ofstream outputFile(filename, std::ios::out);
    
        if (outputFile.is_open()) {
            // 向文件写入数据
            outputFile << "Hello, World!" << std::endl;
            outputFile << 42 << std::endl;
            outputFile << 3.14159 << std::endl;
    
            // 关闭文件
            outputFile.close();
    
            std::cout << "数据已写入文件" << std::endl;
        } else {
            std::cout << "无法打开文件" << std::endl;
        }
    
        return 0;
    }
    
  • 在上述代码中,首先创建一个std::ofstream对象并指定要打开的文件名和打开模式。然后,使用<<操作符向文件中写入数据。最后,使用close方法关闭文件。如果文件无法打开,则输出相应的错误信息。

  • 需要注意的是,std::ofstream对象在销毁时会自动关闭文件,但最好显式调用close方法以确保及时关闭文件。