// cpp03_demo.cpp
// 编译: g++ -std=c++03 cpp03_demo.cpp -o cpp03_demo
// 运行: ./cpp03_demo
// 注意: auto_ptr 在 C++17 起被移除,必须用 C++03/C++11/C++14 标准编译
#include <iostream> // 提供 std::cout / std::cin 输入输出
#include <vector> // 提供 std::vector 动态数组
#include <string> // 提供 std::string 字符串类
#include <map> // 提供 std::map 有序映射
#include <algorithm> // 提供 std::sort 等算法
#include <memory> // 提供 std::auto_ptr
#include <cstddef> // 提供 std::size_t
#include <sstream> // 提供 std::ostringstream / istringstream
#include <stdexcept> // 提供 std::runtime_error 等异常类
// ============================================================
// 1. 值初始化
// ============================================================
void demo_value_init() { // 演示值初始化
std::cout << "===== 值初始化 =====\n"; // 打印分组标题
int x = int(); // 对 int 做值初始化,得到 0
double d = double(); // 对 double 做值初始化,得到 0.0
std::cout << "int() = " << x << ", double() = " << d << "\n"; // 输出结果
std::vector<int> v(10); // 创建 10 个元素,值初始化为 0
std::cout << "vector<int>(10): "; // 提示
for (std::size_t i = 0; i < v.size(); ++i) std::cout << v[i] << " "; // 逐个输出
std::cout << "\n"; // 换行
}
// ============================================================
// 2. 聚合初始化
// ============================================================
struct Point { int x; int y; }; // 聚合体:只有公有数据成员
struct Rect { Point topLeft; Point bottomRight; }; // 嵌套聚合体
void demo_aggregate() { // 演示聚合初始化
std::cout << "\n===== 聚合初始化 =====\n"; // 分组标题
Point p = {1, 2}; // 用花括号按顺序初始化成员
Rect r = { {0, 0}, {100, 50} }; // 嵌套花括号初始化
std::cout << "Point: " << p.x << "," << p.y << "\n"; // 输出 Point
std::cout << "Rect: (" << r.topLeft.x << "," << r.topLeft.y << ") - ("
<< r.bottomRight.x << "," << r.bottomRight.y << ")\n"; // 输出 Rect
}
// ============================================================
// 3. 空基类优化 (EBO)
// ============================================================
struct Empty {}; // 空类,无任何成员
struct WithInt : Empty { int value; }; // 继承空类并加一个 int
void demo_ebo() { // 演示空基类优化
std::cout << "\n===== 空基类优化 =====\n"; // 分组标题
std::cout << "sizeof(Empty) = " << sizeof(Empty) << "\n"; // 空类大小通常为 1
std::cout << "sizeof(WithInt) = " << sizeof(WithInt) << "\n"; // EBO 生效时等于 int
std::cout << "sizeof(int) = " << sizeof(int) << "\n"; // 对照
}
// ============================================================
// 4. 异常规范
// ============================================================
void no_throw_func() throw() { // throw() 表示不抛任何异常
std::cout << "no_throw_func 正常执行\n"; // 输出提示
}
void demo_exception() { // 演示异常规范
std::cout << "\n===== 异常规范 =====\n"; // 分组标题
no_throw_func(); // 调用不抛异常的函数
try { // 开始 try 块
throw std::runtime_error("故意抛出的异常"); // 主动抛出异常
} catch (const std::exception& e) { // 捕获标准异常基类
std::cout << "捕获异常: " << e.what() << "\n"; // 输出异常信息
}
}
// ============================================================
// 5. auto_ptr(C++03 智能指针)
// ============================================================
void demo_auto_ptr() { // 演示 auto_ptr
std::cout << "\n===== auto_ptr =====\n"; // 分组标题
std::auto_ptr<int> p1(new int(42)); // 创建 auto_ptr,接管堆内存
std::cout << "*p1 = " << *p1 << "\n"; // 解引用输出 42
std::auto_ptr<int> p2 = p1; // 拷贝时所有权转移,p1 变为空
std::cout << "*p2 = " << *p2 << "\n"; // p2 现在持有资源
std::cout << "p1 是否为空: " << (p1.get() == 0 ? "是" : "否") << "\n"; // 检查 p1
}
// ============================================================
// 6. STL 与函数对象
// ============================================================
struct CompareDesc { // 自定义比较函数对象
bool operator()(int a, int b) const { // 重载调用运算符
return a > b; // 降序:a > b
}
};
void demo_stl() { // 演示 STL 与函数对象
std::cout << "\n===== STL 与函数对象 =====\n"; // 分组标题
std::vector<int> v; // 创建空 vector
v.push_back(3); v.push_back(1); v.push_back(4); v.push_back(1); v.push_back(5); // 添加元素
std::sort(v.begin(), v.end(), CompareDesc()); // 用函数对象降序排序
std::cout << "降序: "; // 提示
for (std::size_t i = 0; i < v.size(); ++i) std::cout << v[i] << " "; // 输出
std::cout << "\n"; // 换行
std::map<std::string, int> m; // 创建 map
m["apple"] = 3; m["banana"] = 5; // 插入键值对
std::map<std::string, int>::iterator it; // 声明迭代器
for (it = m.begin(); it != m.end(); ++it) // 遍历 map
std::cout << it->first << "=" << it->second << " "; // 输出键值
std::cout << "\n"; // 换行
}
// ============================================================
// 7. RAII
// ============================================================
class Resource { // 演示 RAII 的资源类
public:
Resource(int id) : id_(id) { // 构造:打印提示
std::cout << "Resource " << id_ << " 构造\n";
}
~Resource() { // 析构:打印提示
std::cout << "Resource " << id_ << " 析构\n";
}
int id() const { return id_; } // 访问器
private:
Resource(const Resource&); // 私有声明拷贝构造,禁用拷贝
Resource& operator=(const Resource&); // 私有声明拷贝赋值,禁用拷贝
int id_; // 资源 ID
};
void demo_raii() { // 演示 RAII
std::cout << "\n===== RAII =====\n"; // 分组标题
Resource r(1); // 创建资源,离开作用域自动析构
std::cout << "r.id() = " << r.id() << "\n"; // 使用资源
}
// ============================================================
// 8. 模板
// ============================================================
template <typename T> // 函数模板
T my_max(const T& a, const T& b) { // 返回较大者
return a > b ? a : b; // 三元表达式
}
template <typename T, int N> // 类模板,带非类型参数 N
class FixedArray { // 固定大小数组
public:
T& operator[](int i) { return data_[i]; } // 非 const 下标
int size() const { return N; } // 返回大小
private:
T data_[N]; // 内嵌数组
};
void demo_template() { // 演示模板
std::cout << "\n===== 模板 =====\n"; // 分组标题
std::cout << "my_max(3,7) = " << my_max(3, 7) << "\n"; // 对 int 调用
FixedArray<int, 5> arr; // 创建固定数组
for (int i = 0; i < arr.size(); ++i) arr[i] = i * i; // 填充平方
std::cout << "FixedArray: "; // 提示
for (int i = 0; i < arr.size(); ++i) std::cout << arr[i] << " "; // 输出
std::cout << "\n"; // 换行
}
// ============================================================
// 9. 命名空间
// ============================================================
namespace MyLib { // 自定义命名空间
int value = 100; // 命名空间内的变量
void print() { // 命名空间内的函数
std::cout << "MyLib::print, value = " << value << "\n"; // 输出
}
}
void demo_namespace() { // 演示命名空间
std::cout << "\n===== 命名空间 =====\n"; // 分组标题
MyLib::print(); // 用限定名调用
using MyLib::value; // 用 using 引入单个名字
std::cout << "value = " << value << "\n"; // 直接使用
}
// ============================================================
// 10. 字符串流
// ============================================================
void demo_stringstream() { // 演示字符串流
std::cout << "\n===== 字符串流 =====\n"; // 分组标题
std::ostringstream oss; // 输出字符串流
oss << "x = " << 42 << ", y = " << 3.14; // 拼接内容
std::cout << oss.str() << "\n"; // 取出字符串并输出
std::istringstream iss("123 456"); // 输入字符串流
int a, b; // 两个整数
iss >> a >> b; // 从流中解析
std::cout << "a = " << a << ", b = " << b << "\n"; // 输出
}
// ============================================================
// main
// ============================================================
int main() { // 程序入口
std::cout << "===== C++03 特性演示 =====\n\n"; // 标题
demo_value_init(); // 演示值初始化
demo_aggregate(); // 演示聚合初始化
demo_ebo(); // 演示空基类优化
demo_exception(); // 演示异常规范
demo_auto_ptr(); // 演示 auto_ptr
demo_stl(); // 演示 STL 与函数对象
demo_raii(); // 演示 RAII
demo_template(); // 演示模板
demo_namespace(); // 演示命名空间
demo_stringstream(); // 演示字符串流
std::cout << "\n===== 演示结束 =====\n"; // 结束提示
return 0; // 正常返回
}