用于大型程序的工具专注于 C++ 在大型项目开发中的关键特性,这些工具对于构建可维护、可扩展的复杂系统至关重要。
1. 异常处理进阶
栈展开和资源管理
#include <memory>
#include <fstream>
class DatabaseConnection {
private:
std::string connection_string;
public:
DatabaseConnection(const std::string& conn_str) : connection_string(conn_str) {
std::cout << "Database connected: " << connection_string << std::endl;
}
~DatabaseConnection() {
std::cout << "Database disconnected: " << connection_string << std::endl;
}
void execute(const std::string& query) {
if (query.empty()) {
throw std::invalid_argument("Query cannot be empty");
}
std::cout << "Executing: " << query << std::endl;
}
};
class FileProcessor {
private:
std::ofstream file;
public:
FileProcessor(const std::string& filename) : file(filename) {
if (!file) {
throw std::runtime_error("Cannot open file: " + filename);
}
std::cout << "File opened: " << filename << std::endl;
}
~FileProcessor() {
if (file.is_open()) {
file.close();
std::cout << "File closed" << std::endl;
}
}
void write(const std::string& data) {
file << data << std::endl;
if (!file) {
throw std::runtime_error("Write failed");
}
}
};
void stack_unwinding_demo() {
try {
// 使用智能指针确保资源释放
auto db = std::make_unique<DatabaseConnection>("server=localhost;database=test");
FileProcessor processor("output.txt");
db->execute("SELECT * FROM users");
processor.write("Processing data...");
// 模拟异常
db->execute(""); // 抛出异常
processor.write("This won't be executed");
}
catch (const std::exception& e) {
std::cout << "Exception caught: " << e.what() << std::endl;
// 栈展开会自动调用 db 和 processor 的析构函数
}
}
异常类和继承层次
// 自定义异常层次结构
class NetworkException : public std::runtime_error {
public:
NetworkException(const std::string& msg) : std::runtime_error(msg) {}
};
class ConnectionTimeout : public NetworkException {
public:
ConnectionTimeout() : NetworkException("Connection timeout") {}
};
class AuthenticationFailed : public NetworkException {
public:
AuthenticationFailed() : NetworkException("Authentication failed") {}
};
class DataProcessingException : public std::runtime_error {
public:
DataProcessingException(const std::string& msg) : std::runtime_error(msg) {}
};
void exception_hierarchy_demo() {
try {
// 模拟网络操作
bool timeout_occurred = true;
bool auth_failed = false;
if (timeout_occurred) {
throw ConnectionTimeout();
}
if (auth_failed) {
throw AuthenticationFailed();
}
throw DataProcessingException("Data corruption detected");
}
catch (const ConnectionTimeout& e) {
std::cout << "Handling timeout: " << e.what() << std::endl;
// 重试逻辑
}
catch (const AuthenticationFailed& e) {
std::cout << "Handling auth failure: " << e.what() << std::endl;
// 重新认证逻辑
}
catch (const NetworkException& e) {
std::cout << "Handling generic network error: " << e.what() << std::endl;
}
catch (const std::exception& e) {
std::cout << "Handling other errors: " << e.what() << std::endl;
}
}
noexcept 说明符
class NoExceptDemo {
public:
// 保证不抛出异常的函数
int simple_calculation(int x, int y) noexcept {
return x + y;
}
// 条件性 noexcept
template<typename T>
void swap_values(T& a, T& b) noexcept(noexcept(T(std::move(a))) && noexcept(a.~T())) {
T temp = std::move(a);
a = std::move(b);
b = std::move(temp);
}
// 可能抛出异常的函数
void risky_operation() {
throw std::runtime_error("This might fail");
}
};
void noexcept_demo() {
NoExceptDemo demo;
// noexcept 函数可以在编译期检查
static_assert(noexcept(demo.simple_calculation(1, 2)),
"simple_calculation should be noexcept");
std::cout << "simple_calculation is noexcept: "
<< noexcept(demo.simple_calculation(1, 2)) << std::endl;
std::cout << "risky_operation is noexcept: "
<< noexcept(demo.risky_operation()) << std::endl;
}
2. 命名空间
命名空间的定义和使用
// 公司级别的命名空间组织
namespace CompanyName {
namespace ProjectA {
namespace Database {
class Connection {
public:
void connect() { std::cout << "ProjectA DB connected" << std::endl; }
};
class Query {
public:
void execute() { std::cout << "ProjectA query executed" << std::endl; }
};
}
namespace Network {
class HttpClient {
public:
void request() { std::cout << "ProjectA HTTP request" << std::endl; }
};
}
}
namespace ProjectB {
namespace Database {
// 同名的类在不同的命名空间中
class Connection {
public:
void connect() { std::cout << "ProjectB DB connected" << std::endl; }
};
}
}
// 内联命名空间(版本控制)
namespace v1 {
class API {
public:
void call() { std::cout << "v1 API called" << std::endl; }
};
}
inline namespace v2 { // v2 成为默认版本
class API {
public:
void call() { std::cout << "v2 API called" << std::endl; }
};
}
}
void namespace_demo() {
// 完全限定名
CompanyName::ProjectA::Database::Connection conn1;
conn1.connect();
CompanyName::ProjectB::Database::Connection conn2;
conn2.connect();
// 使用别名
namespace DB = CompanyName::ProjectA::Database;
DB::Query query;
query.execute();
// 内联命名空间的使用
CompanyName::API current_api; // 默认使用 v2
current_api.call();
CompanyName::v1::API old_api; // 显式使用 v1
old_api.call();
}
命名空间别名和 using 声明
namespace VeryLongNamespaceName {
namespace SubNamespace {
class ImportantClass {
public:
void important_method() {
std::cout << "Important work done" << std::endl;
}
};
}
}
// 命名空间别名
namespace VLN = VeryLongNamespaceName;
namespace VSN = VeryLongNamespaceName::SubNamespace;
void using_declarations_demo() {
// using 声明
using VLN::SubNamespace::ImportantClass;
ImportantClass obj1;
obj1.important_method();
// using 指令(谨慎使用)
using namespace VLN::SubNamespace;
ImportantClass obj2;
obj2.important_method();
// 函数内的 using 声明
{
using std::cout;
using std::endl;
cout << "Local using declarations" << endl;
}
}
3. 多重继承
基本多重继承
class Printable {
public:
virtual void print() const = 0;
virtual ~Printable() = default;
};
class Serializable {
public:
virtual std::string serialize() const = 0;
virtual ~Serializable() = default;
};
class Drawable {
public:
virtual void draw() const = 0;
virtual ~Drawable() = default;
};
// 多重继承
class Circle : public Printable, public Serializable, public Drawable {
private:
double radius;
public:
Circle(double r) : radius(r) {}
void print() const override {
std::cout << "Circle with radius: " << radius << std::endl;
}
std::string serialize() const override {
return "Circle:" + std::to_string(radius);
}
void draw() const override {
std::cout << "Drawing circle (radius=" << radius << ")" << std::endl;
}
};
void multiple_inheritance_demo() {
Circle circle(5.0);
// 通过不同接口使用对象
circle.print();
circle.draw();
std::cout << "Serialized: " << circle.serialize() << std::endl;
// 通过基类指针使用
Printable* printable = &circle;
Serializable* serializable = &circle;
Drawable* drawable = &circle;
printable->print();
std::cout << "Via serializable: " << serializable->serialize() << std::endl;
drawable->draw();
}
虚继承和菱形继承问题
// 菱形继承问题示例
class Animal {
protected:
std::string name;
int age;
public:
Animal(const std::string& n, int a) : name(n), age(a) {}
virtual void speak() const = 0;
virtual ~Animal() = default;
};
class Mammal : virtual public Animal { // 虚继承
public:
Mammal(const std::string& n, int a) : Animal(n, a) {}
void give_birth() const {
std::cout << name << " gives birth to live young" << std::endl;
}
};
class WingedAnimal : virtual public Animal { // 虚继承
public:
WingedAnimal(const std::string& n, int a) : Animal(n, a) {}
void fly() const {
std::cout << name << " is flying" << std::endl;
}
};
// 解决菱形继承问题
class Bat : public Mammal, public WingedAnimal {
public:
Bat(const std::string& n, int a) : Animal(n, a), Mammal(n, a), WingedAnimal(n, a) {}
void speak() const override {
std::cout << name << " says: Squeak!" << std::endl;
}
void nocturnal_activities() const {
std::cout << name << " is active at night" << std::endl;
}
};
void virtual_inheritance_demo() {
Bat bat("Bruce", 3);
bat.speak(); // 没有二义性
bat.give_birth(); // 来自 Mammal
bat.fly(); // 来自 WingedAnimal
bat.nocturnal_activities(); // 来自 Bat
// 访问共同的基类成员(没有二义性)
std::cout << "Bat name: " << /* bat.name */ "Bruce" << std::endl; // 实际需要访问器
}
4. 运行时类型识别(RTTI)
dynamic_cast 和 typeid
class Base {
public:
virtual ~Base() = default;
virtual void identify() const {
std::cout << "I am Base" << std::endl;
}
};
class Derived1 : public Base {
public:
void identify() const override {
std::cout << "I am Derived1" << std::endl;
}
void derived1_specific() const {
std::cout << "Derived1 specific method" << std::endl;
}
};
class Derived2 : public Base {
public:
void identify() const override {
std::cout << "I am Derived2" << std::endl;
}
void derived2_specific() const {
std::cout << "Derived2 specific method" << std::endl;
}
};
void rtti_demo() {
std::vector<std::unique_ptr<Base>> objects;
objects.push_back(std::make_unique<Derived1>());
objects.push_back(std::make_unique<Derived2>());
objects.push_back(std::make_unique<Base>());
for (const auto& obj : objects) {
// 使用 typeid 获取类型信息
std::cout << "Type: " << typeid(*obj).name() << std::endl;
// 使用 dynamic_cast 进行安全的向下转型
if (auto d1 = dynamic_cast<Derived1*>(obj.get())) {
std::cout << " -> This is Derived1, calling specific method: ";
d1->derived1_specific();
}
else if (auto d2 = dynamic_cast<Derived2*>(obj.get())) {
std::cout << " -> This is Derived2, calling specific method: ";
d2->derived2_specific();
}
else {
std::cout << " -> This is Base or unknown derived type" << std::endl;
}
obj->identify();
std::cout << std::endl;
}
}
type_info 类
void type_info_demo() {
int i = 42;
double d = 3.14;
std::string s = "hello";
const std::type_info& ti1 = typeid(i);
const std::type_info& ti2 = typeid(d);
const std::type_info& ti3 = typeid(s);
std::cout << "int: " << ti1.name() << std::endl;
std::cout << "double: " << ti2.name() << std::endl;
std::cout << "string: " << ti3.name() << std::endl;
// 类型比较
std::cout << "i and d same type: " << (ti1 == ti2) << std::endl;
std::cout << "i and i same type: " << (ti1 == typeid(int)) << std::endl;
// 哈希值(C++11)
std::cout << "int hash: " << ti1.hash_code() << std::endl;
std::cout << "double hash: " << ti2.hash_code() << std::endl;
}
5. 枚举类
有作用域枚举
// 传统枚举的问题
enum Color { RED, GREEN, BLUE }; // 可能冲突
enum TrafficLight { RED, YELLOW, GREEN }; // 错误:重定义
// 枚举类解决冲突
enum class Color { RED, GREEN, BLUE };
enum class TrafficLight { RED, YELLOW, GREEN };
enum class Priority : uint8_t { LOW, MEDIUM, HIGH, CRITICAL }; // 指定底层类型
void enum_class_demo() {
Color c = Color::RED;
TrafficLight light = TrafficLight::GREEN;
Priority p = Priority::HIGH;
// 必须使用作用域操作符
if (c == Color::RED) {
std::cout << "Color is red" << std::endl;
}
// 不会隐式转换为整数
// int color_value = c; // 错误!
int color_value = static_cast<int>(c); // 需要显式转换
std::cout << "Color value: " << color_value << std::endl;
// 指定底层类型的好处
std::cout << "Size of Priority: " << sizeof(Priority) << " bytes" << std::endl;
std::cout << "Priority value: " << static_cast<int>(p) << std::endl;
}
枚举类的高级用法
enum class FilePermission : uint8_t {
READ = 1 << 0, // 00000001
WRITE = 1 << 1, // 00000010
EXECUTE = 1 << 2 // 00000100
};
// 重载操作符使枚举类更易用
constexpr FilePermission operator|(FilePermission lhs, FilePermission rhs) {
return static_cast<FilePermission>(
static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
}
constexpr FilePermission operator&(FilePermission lhs, FilePermission rhs) {
return static_cast<FilePermission>(
static_cast<uint8_t>(lhs) & static_cast<uint8_t>(rhs));
}
constexpr bool has_permission(FilePermission perms, FilePermission check) {
return (perms & check) == check;
}
void advanced_enum_demo() {
FilePermission user_perms = FilePermission::READ | FilePermission::WRITE;
std::cout << "User permissions: " << static_cast<int>(user_perms) << std::endl;
if (has_permission(user_perms, FilePermission::READ)) {
std::cout << "User can read" << std::endl;
}
if (!has_permission(user_perms, FilePermission::EXECUTE)) {
std::cout << "User cannot execute" << std::endl;
}
// 添加权限
user_perms = user_perms | FilePermission::EXECUTE;
std::cout << "After adding execute: " << static_cast<int>(user_perms) << std::endl;
}
6. 实践项目:插件系统架构
#include <map>
#include <memory>
#include <functional>
// 插件接口
class IPlugin {
public:
virtual ~IPlugin() = default;
virtual std::string name() const = 0;
virtual void initialize() = 0;
virtual void execute() = 0;
virtual void shutdown() = 0;
};
// 插件管理器
class PluginManager {
private:
std::map<std::string, std::unique_ptr<IPlugin>> plugins;
public:
template<typename T, typename... Args>
void register_plugin(const std::string& name, Args&&... args) {
static_assert(std::is_base_of_v<IPlugin, T>,
"T must derive from IPlugin");
plugins[name] = std::make_unique<T>(std::forward<Args>(args)...);
}
IPlugin* get_plugin(const std::string& name) {
auto it = plugins.find(name);
return it != plugins.end() ? it->second.get() : nullptr;
}
void initialize_all() {
for (auto& [name, plugin] : plugins) {
std::cout << "Initializing plugin: " << name << std::endl;
plugin->initialize();
}
}
void execute_all() {
for (auto& [name, plugin] : plugins) {
std::cout << "Executing plugin: " << name << std::endl;
plugin->execute();
}
}
void shutdown_all() {
for (auto& [name, plugin] : plugins) {
std::cout << "Shutting down plugin: " << name << std::endl;
plugin->shutdown();
}
}
};
// 具体插件实现
class LoggerPlugin : public IPlugin {
public:
std::string name() const override { return "Logger"; }
void initialize() override {
std::cout << "LoggerPlugin: Initializing..." << std::endl;
}
void execute() override {
std::cout << "LoggerPlugin: Logging message..." << std::endl;
}
void shutdown() override {
std::cout << "LoggerPlugin: Shutting down..." << std::endl;
}
};
class NetworkPlugin : public IPlugin {
public:
std::string name() const override { return "Network"; }
void initialize() override {
std::cout << "NetworkPlugin: Initializing connections..." << std::endl;
}
void execute() override {
std::cout << "NetworkPlugin: Sending data..." << std::endl;
}
void shutdown() override {
std::cout << "NetworkPlugin: Closing connections..." << std::endl;
}
};
void plugin_system_demo() {
PluginManager manager;
// 注册插件
manager.register_plugin<LoggerPlugin>("Logger");
manager.register_plugin<NetworkPlugin>("Network");
// 使用插件系统
manager.initialize_all();
std::cout << "---" << std::endl;
manager.execute_all();
std::cout << "---" << std::endl;
manager.shutdown_all();
// 动态获取插件
if (auto plugin = manager.get_plugin("Logger")) {
std::cout << "Found plugin: " << plugin->name() << std::endl;
}
}
最佳实践总结
- 使用 RAII 管理资源,确保异常安全
- 合理组织命名空间,避免名称冲突
- 谨慎使用多重继承,优先使用组合
- 使用枚举类代替传统枚举
- 限制 RTTI 的使用,优先使用虚函数
392

被折叠的 条评论
为什么被折叠?



