当前位置: 首页 > java >正文

57 C++ 现代C++编程艺术6-类的内部类

C++ 现代C++编程艺术6-类的内部类

文章目录

  • C++ 现代C++编程艺术6-类的内部类
    • 一、内部类基础概念
    • 二、核心应用场景与代码示例
      • 1. 隐藏派生类(实现工厂模式)
      • 2. 模板化内部类(泛型编程)
      • 3. 模板特化与友元关系
    • 三、高级应用技巧
    • 四、关键注意事项
    • 五、应用场景总结

C++ 内部类(嵌套类)是定义在另一个类内部的类,主要用于封装关联逻辑、隐藏实现细节或优化代码组织。

一、内部类基础概念

内部类(嵌套类) 是定义在另一个类内部的类,主要用于:

  • 封装关联逻辑:将紧密相关的类组织在一起
  • 隐藏实现细节:限制内部类的可见性
  • 优化代码组织:提高代码的内聚性和可读性
  • 减少命名冲突:通过类作用域隔离标识符
class Outer {
public:class Inner {  // 内部类声明 // 成员定义};
};

二、核心应用场景与代码示例

1. 隐藏派生类(实现工厂模式)

// 基类接口 
class Shape {
public:virtual void draw() = 0;virtual ~Shape() = default;
};class ShapeFactory {
public:static Shape* createCircle() { return new InnerCircle();  // 返回内部类实例 }
private:// 私有内部类实现 class InnerCircle : public Shape {public:void draw() override {std::cout << "Drawing Circle" << std::endl;}};
};int main() {// 使用示例 Shape* circle = ShapeFactory::createCircle();circle->draw();  // 输出: Drawing Circle delete circle;return 0;
}

2. 模板化内部类(泛型编程)

#include <iostream>
#include <vector>
#include <stdexcept>  // 包含标准异常头文件template <typename T>
class Matrix {
public:// 默认构造函数创建空矩阵 Matrix() = default;// 带参数的构造函数Matrix(size_t rows, size_t cols) : data(rows, std::vector<T>(cols)) {}// 模板内部类:行迭代器 class RowIterator {private:T* currentRow;size_t rowSize = 0;  // 存储行大小信息 public:explicit RowIterator(T* row, size_t size) : currentRow(row), rowSize(size) {}// 下标访问运算符 T& operator[](size_t col) {if (col >= rowSize) {throw std::out_of_range("Column index out of range");}return currentRow[col];}// 只读版本的下标访问const T& operator[](size_t col) const {if (col >= rowSize) {throw std::out_of_range("Column index out of range");}return currentRow[col];}// 获取行首指针 T* begin() { return currentRow; }// 获取行尾指针 T* end() { return currentRow + rowSize; }// 获取行大小 size_t size() const { return rowSize; }};// 矩阵行访问运算符 RowIterator operator[](size_t row) {if (row >= data.size())  {throw std::out_of_range("Row index out of range");}// 传递行指针和行大小return RowIterator(data[row].data(), data[row].size());}// 只读版本的行访问 const RowIterator operator[](size_t row) const {if (row >= data.size())  {throw std::out_of_range("Row index out of range");}return RowIterator(data[row].data(), data[row].size());}// 安全元素访问接口 T& at(size_t row, size_t col) {if (row >= data.size())  {throw std::out_of_range("Row index out of range");}if (col >= data[row].size()) {throw std::out_of_range("Column index out of range");}return data[row][col];}// 只读安全访问 const T& at(size_t row, size_t col) const {if (row >= data.size())  {throw std::out_of_range("Row index out of range");}if (col >= data[row].size()) {throw std::out_of_range("Column index out of range");}return data[row][col];}// 获取行数size_t rows() const { return data.size();  }// 获取列数(假设所有行大小相同)size_t cols() const { if (data.empty())  return 0;return data[0].size(); }// 改变矩阵大小 void resize(size_t rows, size_t cols) {data.resize(rows); for (auto& row : data) {row.resize(cols); }}private:std::vector<std::vector<T>> data;
};int main() {try {// 创建3x4矩阵Matrix<int> mat1(3, 4);// 初始化矩阵值 for (size_t i = 0; i < mat1.rows();  ++i) {for (size_t j = 0; j < mat1.cols();  ++j) {mat1[i][j] = static_cast<int>(i * mat1.cols()  + j);}}// 访问元素 auto row = mat1[2];  // 获取第三行 int value = row[3];   // 访问第四列元素 std::cout << "Value at [2][3]: " << value << std::endl;  // 应该输出11 // 测试边界检查try {int invalid = mat1[5][2];  // 越界访问 } catch (const std::out_of_range& e) {std::cout << "Caught exception: " << e.what()  << std::endl;}// 使用默认构造函数创建矩阵 Matrix<float> mat2;mat2.resize(2,  3);  // 调整大小// 填充数据 for (size_t i = 0; i < mat2.rows();  ++i) {for (size_t j = 0; j < mat2.cols();  ++j) {mat2[i][j] = static_cast<float>(i * 10 + 0.123);}}// 访问元素std::cout << "Value at [1][2]: " << mat2[1][2] << std::endl;  // 应该输出 10.123} catch (const std::exception& e) {std::cerr << "Error: " << e.what()  << std::endl;return 1;}return 0;
}

3. 模板特化与友元关系

template<typename T>
class Container {T data;// 每个模板实例独立声明友元friend class Iterator;public:class Iterator {public:void reset(Container& c) { c.data = T{};  // 访问外部类私有成员 }const T& get(const Container& c) const {return c.data;  // 只读访问 }};
};// 使用示例 
Container<int> intContainer;
Container<int>::Iterator intIter;
intIter.reset(intContainer);Container<std::string> strContainer;
Container<std::string>::Iterator strIter;
strIter.reset(strContainer);

三、高级应用技巧

  1. 元编程支持

    class TypeTraits {
    public:// 类型特征提取内部类 template<typename T>class TypeInfo {public:static constexpr bool is_integral = std::is_integral_v<T>;static constexpr bool is_pointer = std::is_pointer_v<T>;static std::string name() {if constexpr (is_integral) return "Integral";else if constexpr (is_pointer) return "Pointer";else return "Unknown";}};
    };// 使用示例 
    std::cout << TypeTraits::TypeInfo<int>::name();  // 输出: Integral
    std::cout << TypeTraits::TypeInfo<int*>::name(); // 输出: Pointer 
    
  2. 访问控制模式

    class SecureSystem {
    private:int secretKey = 0xDEADBEEF;// 特权访问内部类class PrivilegedAccess {public:static int getKey(SecureSystem& sys) {return sys.secretKey;  // 直接访问私有成员}};public:// 公开API委托特权访问int getPublicKey() {return PrivilegedAccess::getKey(*this);}
    };// 使用示例
    SecureSystem system;
    int key = system.getPublicKey();  // 通过受控接口访问
    

四、关键注意事项

  1. 访问权限规则

    访问方向权限要求示例
    内部类→外部类需通过实例访问outerObj.member
    外部类→内部类需声明为友元friend class Outer;
    静态成员访问直接访问Outer::staticMember
  2. 生命周期管理

    class ResourceHolder {
    public:class ResourceHandle {public:ResourceHandle(ResourceHolder& holder) : parent(holder) {}void useResource() {if (!parent.resourceActive) {throw std::runtime_error("Resource unavailable");}// 使用资源...}private:ResourceHolder& parent;  // 持有父类引用 };ResourceHandle getHandle() {return ResourceHandle(*this);}~ResourceHolder() {resourceActive = false;  // 使所有handle失效}private:bool resourceActive = true;
    };
    
  3. 设计最佳推荐

    1. 封装边界:使用private内部类彻底隐藏实现
    2. 接口隔离:通过公共内部类定义子模块接口
    3. 模板特化:为不同模板实例提供定制化内部类
    4. 循环引用:避免内部类与外部类相互依赖
    5. 编译器影响:注意嵌套深度对编译性能的影响

五、应用场景总结

场景技术方案优势
实现隐藏私有内部类 + 工厂方法完全封装实现细节
泛型迭代器模板内部类 + 运算符重载类型安全遍历
有限继承保护内部类 + 静态工厂控制派生范围
特权访问友元内部类 + 代理接口细粒度权限控制
编译期计算静态成员内部类 + constexpr零开销抽象

内部类应保持职责单一,深度嵌套超过两层时,应考虑重构为独立类。

​ 内部类作为C++强大的封装机制,合理使用可显著提升代码的模块化和类型安全性。在框架设计、模板元编程和接口隔离等场景中,它能提供优雅的解决方案,但需警惕过度使用导致的编译依赖和代码可读性问题。

http://www.xdnf.cn/news/18658.html

相关文章:

  • DBeaver连接SQL Server集成认证问题解决方案
  • 题解:P13822 「Diligent-OI R2 B」白露为霜_奇偶性_数学归纳_算法竞赛C++
  • 将C++资源管理测试框架整合到GitLab CI/CD的完整实践指南
  • ffmpeg 问答系列-> mux 部分
  • C6.1:发射极偏置放大器
  • 阿里 通义千问 Java23种设计模式
  • IDM 下载失败排查指南:全面解析与解决方案
  • 深入解析 std::enable_if:原理、用法与现代 C++ 实践
  • 编程与数学 02-017 Python 面向对象编程 20课题、迭代器模式
  • 大数据毕业设计选题推荐-基于大数据的丙型肝炎患者数据可视化分析系统-Hadoop-Spark-数据可视化-BigData
  • 深入解析十大经典排序算法原理与实现
  • 室联人形机器人:家政服务任务结构化、技术要点、深入应用FPGA的控制系统框架设计(整合版A)
  • 【运维进阶】高可用和负载均衡技术
  • Django的Serializers与 fastapi 的Pydantic
  • 【R语言】R语言中 rbind() 与 merge() 的区别详解
  • 网络编程-创建TCP协议服务器
  • 疏老师-python训练营-Day54Inception网络及其思考
  • 屏幕类型与信号接口
  • 【KO】前端面试一
  • LLaMA-Factory 中配置文件或命令行里各个参数的含义
  • 如何利用 DeepSeek 提升工作效率
  • 10.Shell脚本修炼手册---脚本的条件测试与比较
  • 国家自然科学基金(国自然基金)申请技巧详解
  • 深度学习入门:神经网络
  • 【2025CVPR-目标检测方向】UniMamba:基于激光雷达的3D目标检测,采用分组高效曼巴语进行统一空间信道表示学习
  • Q/DR/CX7.2-2020 是中国企业标准体系中
  • 一个备份、去除、新增k8s的node标签脚本
  • `strdup` 字符串复制函数
  • 【JVM内存结构系列】二、线程私有区域详解:程序计数器、虚拟机栈、本地方法栈——搞懂栈溢出与线程隔离
  • 奇怪的前端面试题