[c/c++] 黄强 C++ Boost库高级编程-高效跨平台的C++模板库视频课程

53 阅读6分钟

C++ Boost库高级编程:现代C++开发的利器

Boost库作为C++标准库的延伸,提供了大量经过工业级验证的组件,是每个C++开发者必须掌握的重要工具集。

1. Boost库概述与环境配置

Boost库是一个经过同行评审、可移植的C++源码库,它作为C++标准库的延伸,提供了许多高质量的工具和组件。许多Boost组件后来被纳入C++标准,如智能指针、线程库、正则表达式等。

1.1 环境安装与配置

Linux环境安装:

# Ubuntu/Debian
sudo apt-get install libboost-all-dev

# CentOS/RHEL
sudo yum install boost-devel

# 或者从源码编译
wget https://dl.bintray.com/boostorg/release/1.75.0/source/boost_1_75_0.tar.gz
tar -xzf boost_1_75_0.tar.gz
cd boost_1_75_0
./bootstrap.sh
./b2 install

CMake项目配置:

cmake_minimum_required(VERSION 3.10)
project(BoostDemo)

set(CMAKE_CXX_STANDARD 17)

# 查找Boost库
find_package(Boost 1.70 REQUIRED COMPONENTS
    filesystem
    system
    thread
    chrono
    program_options
    regex
)

if(Boost_FOUND)
    include_directories(${Boost_INCLUDE_DIRS})
    add_executable(boost_demo main.cpp)
    target_link_libraries(boost_demo ${Boost_LIBRARIES})
endif()

2. 智能指针深度解析

2.1 shared_ptr智能指针

#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/weak_ptr.hpp>
#include <iostream>
#include <vector>
#include <memory>

class Resource {
private:
    std::string name_;
public:
    explicit Resource(const std::string& name) : name_(name) {
        std::cout << "Resource '" << name_ << "' constructed" << std::endl;
    }
    
    void use() const {
        std::cout << "Using resource: " << name_ << std::endl;
    }
    
    ~Resource() {
        std::cout << "Resource '" << name_ << "' destroyed" << std::endl;
    }
};

// 工厂函数
boost::shared_ptr<Resource> createResource(const std::string& name) {
    return boost::make_shared<Resource>(name);
}

void shared_ptr_demo() {
    std::cout << "=== shared_ptr Demo ===" << std::endl;
    
    // 创建shared_ptr
    boost::shared_ptr<Resource> ptr1 = createResource("Database Connection");
    ptr1->use();
    
    {
        // 共享所有权
        boost::shared_ptr<Resource> ptr2 = ptr1;
        std::cout << "Use count inside scope: " << ptr1.use_count() << std::endl;
        ptr2->use();
    }
    
    std::cout << "Use count after scope: " << ptr1.use_count() << std::endl;
    
    // 在容器中使用
    std::vector<boost::shared_ptr<Resource>> resources;
    resources.push_back(createResource("File Handler 1"));
    resources.push_back(createResource("File Handler 2"));
    resources.push_back(createResource("Network Socket"));
    
    for (const auto& resource : resources) {
        resource->use();
    }
}

2.2 weak_ptr解决循环引用

class Controller;

class Device {
private:
    boost::shared_ptr<Controller> controller_;
public:
    void setController(const boost::shared_ptr<Controller>& controller) {
        controller_ = controller;
    }
    
    void performTask() {
        std::cout << "Device performing task" << std::endl;
    }
    
    ~Device() {
        std::cout << "Device destroyed" << std::endl;
    }
};

class Controller {
private:
    boost::weak_ptr<Device> device_;  // 使用weak_ptr避免循环引用
public:
    void setDevice(const boost::shared_ptr<Device>& device) {
        device_ = device;
    }
    
    void sendCommand() {
        // 尝试获取shared_ptr
        if (boost::shared_ptr<Device> device = device_.lock()) {
            device->performTask();
        } else {
            std::cout << "Device no longer exists" << std::endl;
        }
    }
    
    ~Controller() {
        std::cout << "Controller destroyed" << std::endl;
    }
};

void weak_ptr_demo() {
    std::cout << "\n=== weak_ptr Demo (循环引用解决方案) ===" << std::endl;
    
    boost::shared_ptr<Device> device(new Device());
    boost::shared_ptr<Controller> controller(new Controller());
    
    device->setController(controller);
    controller->setDevice(device);
    
    controller->sendCommand();
    
    // 当device和controller超出作用域时,会被正确销毁
    std::cout << "Reference counts - Device: " << device.use_count() 
              << ", Controller: " << controller.use_count() << std::endl;
}

3. 文件系统操作

#include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp>
#include <iostream>
#include <fstream>

namespace fs = boost::filesystem;

void filesystem_demo() {
    std::cout << "\n=== Filesystem Demo ===" << std::endl;
    
    // 创建目录
    fs::path dir_path("test_directory");
    boost::system::error_code ec;
    
    if (fs::create_directory(dir_path, ec)) {
        std::cout << "Directory created: " << dir_path << std::endl;
    } else {
        std::cout << "Failed to create directory: " << ec.message() << std::endl;
    }
    
    // 创建测试文件
    fs::path file_path = dir_path / "test.txt";
    std::ofstream file(file_path.string());
    file << "Hello Boost Filesystem!" << std::endl;
    file.close();
    
    // 检查文件属性
    if (fs::exists(file_path)) {
        std::cout << "File exists: " << file_path << std::endl;
        std::cout << "File size: " << fs::file_size(file_path) << " bytes" << std::endl;
        std::cout << "Last modified: " << fs::last_write_time(file_path) << std::endl;
    }
    
    // 遍历目录
    std::cout << "\nDirectory contents:" << std::endl;
    for (const auto& entry : fs::directory_iterator(dir_path)) {
        std::cout << "  " << entry.path().filename() 
                  << " (" << (fs::is_directory(entry.status()) ? "dir" : "file") << ")" 
                  << std::endl;
    }
    
    // 递归遍历
    std::cout << "\nRecursive directory contents:" << std::endl;
    for (const auto& entry : fs::recursive_directory_iterator(dir_path)) {
        std::cout << "  " << entry.path() << std::endl;
    }
    
    // 清理
    fs::remove_all(dir_path, ec);
    if (!ec) {
        std::cout << "\nCleanup completed" << std::endl;
    }
}

4. 多线程编程

#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/chrono.hpp>
#include <queue>
#include <iostream>

class ThreadSafeQueue {
private:
    std::queue<int> queue_;
    mutable boost::mutex mutex_;
    boost::condition_variable cond_;
    
public:
    void push(int value) {
        boost::unique_lock<boost::mutex> lock(mutex_);
        queue_.push(value);
        lock.unlock();
        cond_.notify_one();
    }
    
    bool try_pop(int& value) {
        boost::unique_lock<boost::mutex> lock(mutex_);
        if (queue_.empty()) {
            return false;
        }
        value = queue_.front();
        queue_.pop();
        return true;
    }
    
    bool wait_and_pop(int& value) {
        boost::unique_lock<boost::mutex> lock(mutex_);
        while (queue_.empty()) {
            cond_.wait(lock);
        }
        value = queue_.front();
        queue_.pop();
        return true;
    }
    
    size_t size() const {
        boost::unique_lock<boost::mutex> lock(mutex_);
        return queue_.size();
    }
};

void producer(ThreadSafeQueue& queue, int id) {
    for (int i = 0; i < 5; ++i) {
        int value = id * 100 + i;
        queue.push(value);
        std::cout << "Producer " << id << " produced: " << value << std::endl;
        boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
    }
}

void consumer(ThreadSafeQueue& queue, int id) {
    for (int i = 0; i < 5; ++i) {
        int value;
        queue.wait_and_pop(value);
        std::cout << "Consumer " << id << " consumed: " << value << std::endl;
        boost::this_thread::sleep_for(boost::chrono::milliseconds(150));
    }
}

void thread_demo() {
    std::cout << "\n=== Multithreading Demo ===" << std::endl;
    
    ThreadSafeQueue queue;
    
    // 创建生产者和消费者线程
    boost::thread_group threads;
    
    // 启动2个生产者
    threads.create_thread(boost::bind(producer, boost::ref(queue), 1));
    threads.create_thread(boost::bind(producer, boost::ref(queue), 2));
    
    // 启动2个消费者
    threads.create_thread(boost::bind(consumer, boost::ref(queue), 1));
    threads.create_thread(boost::bind(consumer, boost::ref(queue), 2));
    
    // 等待所有线程完成
    threads.join_all();
    
    std::cout << "All threads completed" << std::endl;
}

5. 正则表达式

#include <boost/regex.hpp>
#include <iostream>
#include <string>

void regex_demo() {
    std::cout << "\n=== Regular Expressions Demo ===" << std::endl;
    
    // 电子邮件验证
    std::string email_pattern = 
        R"(^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$)";
    boost::regex email_regex(email_pattern);
    
    std::vector<std::string> emails = {
        "user@example.com",
        "invalid.email",
        "test@domain.co.uk",
        "another@sub.domain.com"
    };
    
    std::cout << "Email validation:" << std::endl;
    for (const auto& email : emails) {
        bool valid = boost::regex_match(email, email_regex);
        std::cout << "  " << email << " : " << (valid ? "VALID" : "INVALID") << std::endl;
    }
    
    // 文本搜索和替换
    std::string text = "My phone numbers are 123-456-7890 and 987-654-3210. "
                      "Call me at 555-123-4567.";
    
    boost::regex phone_regex(R"(\b\d{3}-\d{3}-\d{4}\b)");
    
    std::cout << "\nPhone numbers found:" << std::endl;
    boost::sregex_iterator it(text.begin(), text.end(), phone_regex);
    boost::sregex_iterator end;
    
    for (; it != end; ++it) {
        std::cout << "  " << it->str() << std::endl;
    }
    
    // 替换电话号码
    std::string masked_text = boost::regex_replace(
        text, 
        phone_regex, 
        "XXX-XXX-XXXX",
        boost::match_default | boost::format_sed
    );
    
    std::cout << "\nMasked text:" << std::endl;
    std::cout << "  " << masked_text << std::endl;
    
    // 分组提取
    std::string log_entry = "2024-01-15 14:30:25 [ERROR] Database connection failed";
    boost::regex log_regex(R"(^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) \[(\w+)\] (.+)$)");
    
    boost::smatch matches;
    if (boost::regex_match(log_entry, matches, log_regex)) {
        std::cout << "\nLog entry parsed:" << std::endl;
        std::cout << "  Date: " << matches[1] << std::endl;
        std::cout << "  Time: " << matches[2] << std::endl;
        std::cout << "  Level: " << matches[3] << std::endl;
        std::cout << "  Message: " << matches[4] << std::endl;
    }
}

6. 日期时间处理

#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <iostream>

void datetime_demo() {
    std::cout << "\n=== Date and Time Demo ===" << std::endl;
    
    namespace pt = boost::posix_time;
    namespace gr = boost::gregorian;
    
    // 当前时间
    pt::ptime now = pt::second_clock::local_time();
    std::cout << "Current time: " << now << std::endl;
    
    // 日期计算
    gr::date today = gr::day_clock::local_day();
    gr::date next_week = today + gr::days(7);
    gr::date last_month = today - gr::months(1);
    
    std::cout << "Today: " << today << std::endl;
    std::cout << "Next week: " << next_week << std::endl;
    std::cout << "Last month: " << last_month << std::endl;
    
    // 时间段计算
    pt::ptime start_time = pt::microsec_clock::local_time();
    
    // 模拟一些工作
    for (int i = 0; i < 1000000; ++i) {
        volatile int x = i * i;
    }
    
    pt::ptime end_time = pt::microsec_clock::local_time();
    pt::time_duration duration = end_time - start_time;
    
    std::cout << "Operation took: " << duration.total_microseconds() << " microseconds" << std::endl;
    
    // 日期迭代
    gr::date start_date(2024, 1, 1);
    gr::date end_date(2024, 1, 10);
    
    std::cout << "\nDates from " << start_date << " to " << end_date << ":" << std::endl;
    for (gr::day_iterator it(start_date); it <= end_date; ++it) {
        std::cout << "  " << *it << " (" << it->day_of_week() << ")" << std::endl;
    }
    
    // 时间格式化
    pt::ptime custom_time(gr::date(2024, 1, 15), pt::hours(14) + pt::minutes(30));
    std::cout << "\nCustom time: " << custom_time << std::endl;
    
    // 时区处理(简单示例)
    pt::ptime utc_time = pt::second_clock::universal_time();
    std::cout << "UTC time: " << utc_time << std::endl;
}

7. 程序选项解析

#include <boost/program_options.hpp>
#include <iostream>
#include <fstream>

namespace po = boost::program_options;

void program_options_demo(int argc, char* argv[]) {
    std::cout << "\n=== Program Options Demo ===" << std::endl;
    
    try {
        po::options_description desc("Allowed options");
        desc.add_options()
            ("help,h", "produce help message")
            ("input,i", po::value<std::string>(), "input file")
            ("output,o", po::value<std::string>(), "output file")
            ("verbose,v", po::value<int>()->implicit_value(1), "verbose level")
            ("threads,t", po::value<int>()->default_value(4), "number of threads")
            ("config,c", po::value<std::string>(), "configuration file")
        ;
        
        po::variables_map vm;
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);
        
        if (vm.count("help")) {
            std::cout << desc << std::endl;
            return;
        }
        
        if (vm.count("input")) {
            std::cout << "Input file: " << vm["input"].as<std::string>() << std::endl;
        } else {
            std::cout << "Input file not specified." << std::endl;
        }
        
        if (vm.count("output")) {
            std::cout << "Output file: " << vm["output"].as<std::string>() << std::endl;
        }
        
        if (vm.count("verbose")) {
            std::cout << "Verbose level: " << vm["verbose"].as<int>() << std::endl;
        }
        
        std::cout << "Threads: " << vm["threads"].as<int>() << std::endl;
        
        // 配置文件解析
        if (vm.count("config")) {
            std::string config_file = vm["config"].as<std::string>();
            std::ifstream ifs(config_file.c_str());
            if (!ifs) {
                std::cout << "Cannot open config file: " << config_file << std::endl;
            } else {
                po::store(po::parse_config_file(ifs, desc), vm);
                po::notify(vm);
                std::cout << "Config file loaded: " << config_file << std::endl;
            }
        }
        
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }
}

8. 完整示例程序

#include <iostream>
#include <string>

// 模拟命令行参数
int main(int argc, char* argv[]) {
    std::cout << "Boost Library Advanced Programming Demo\n" << std::endl;
    
    // 如果提供了命令行参数,使用它们
    if (argc > 1) {
        program_options_demo(argc, argv);
    }
    
    // 运行各个演示
    shared_ptr_demo();
    weak_ptr_demo();
    filesystem_demo();
    thread_demo();
    regex_demo();
    datetime_demo();
    
    std::cout << "\n=== All Demos Completed Successfully! ===" << std::endl;
    
    return 0;
}

9. 编译和运行

编译命令:

# 使用g++编译
g++ -std=c++17 -o boost_demo main.cpp -lboost_system -lboost_filesystem -lboost_thread -lboost_regex -lboost_date_time -lboost_program_options -lpthread

# 或者使用CMake
mkdir build
cd build
cmake ..
make
./boost_demo --help

示例运行:

./boost_demo --input data.txt --output result.txt --verbose 2 --threads 8

总结

Boost库提供了丰富的组件来增强C++的开发能力:

  1. 智能指针:自动内存管理,避免内存泄漏
  2. 文件系统:跨平台的文件和目录操作
  3. 多线程:高级线程管理和同步机制
  4. 正则表达式:强大的文本处理能力
  5. 日期时间:精确的时间计算和日期处理
  6. 程序选项:灵活的命令行参数解析

这些组件不仅功能强大,而且性能优秀,是C++高级编程不可或缺的工具。通过掌握Boost库,开发者可以大大提高开发效率和代码质量。