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

C++类的简单介绍

一、构造函数

  1. 默认构造函数

    • 触发场景:对象默认初始化、值初始化、构造数组元素

    • 编译器生成规则:若未定义任何构造函数则自动生成

    • =default:显式要求编译器生成默认版本

    • =delete:禁止默认构造

    • 必须自定义的场景

      • 类包含const成员或引用成员

      • 存在不可默认构造的成员对象

  2. 构造函数的初始化与赋值

    • 初始化列表

      • 必须使用的情况:const成员、引用成员、无默认构造函数的类类型成员

      • 初始化顺序:按成员声明顺序,与初始化列表顺序无关

    • 效率对比:初始化列表直接构造,赋值方式=构造+拷贝赋值

class Box {  
public:  
    Box() = default;            // 显式要求编译器生成默认构造  
    Box(int s) : size(s) {}     // 自定义构造函数  
private:  
    int size{0};  
};  

int main() {  
    Box b1;                     // 调用默认构造  
    Box b2{};                   // 值初始化  
    Box arr[3];                 // 数组元素默认构造  
}  

  1. 委托构造函数

    • C++11特性:一个构造函数调用同类的其他构造函数

    class MyClass {  
        MyClass(int a) : x(a) {}  
        MyClass() : MyClass(0) {} // 委托构造  
    };  
  2. 类型转换与explicit

    • 隐式转换规则:单参数构造函数定义转换规则

    • explicit作用:禁止隐式转换,强制显式调用

    • 典型应用场景:智能指针、std::vector的单参数构造函数

class Date {  
public:  
    Date(int d) : day(d) {}          // 允许隐式转换  
    explicit Date(string s) { ... }  // 禁止隐式转换  
};  

void printDate(Date d) { ... }  

int main() {  
    printDate(25);            // 合法:Date(25)隐式转换  
    printDate("2023-01-01"); // 错误:explicit构造函数需显式转换  
    printDate(Date("2023-01-01")); // 正确  
}  

二、类的封装

  1. 实现机制

    • 访问控制:public/private/protected

    • 接口暴露:通过公有成员函数操作私有数据

    • 封装的意义

      • 数据保护

      • 接口稳定性

      • 实现与接口解耦

        class BankAccount {  
        public:  
            void deposit(int amount) {  
                if(amount > 0) balance += amount;  
            }  
            int getBalance() const { return balance; }  
        private:  
            int balance{0};        // 数据私有化  
        };  
        
        int main() {  
            BankAccount acc;  
            acc.deposit(100);      // 通过公有接口操作  
            // acc.balance = 1000; // 错误:私有成员无法访问  
        }  
  2. class vs struct

    • 唯一区别:默认访问权限(class默认privatestruct默认public

    • 使用惯例:

      • struct用于纯数据聚合

      • class用于需要封装行为的对象

        // class默认private  
        class PointClass {  
            int x;  // 默认private  
        public:  
            int y;  
        };  
        
        // struct默认public  
        struct PointStruct {  
            int x;  // 默认public  
        private:  
            int y;  
        };  

三、特殊成员

  1. 可变数据成员(mutable

    • 允许在const成员函数中修改

    • 典型应用:缓存、互斥锁、引用计数

      class Cache {  
      public:  
          int getValue() const {  
              accessCount++;     // 允许修改mutable成员  
              return cachedValue;  
          }  
      private:  
          int cachedValue;  
          mutable int accessCount{0};  
      };  
  2. 静态成员

    • 静态数据成员

      • 类内声明 + 类外定义(C++17支持类内初始化)

      • 生命周期:程序运行期间

    • 静态成员函数

      • this指针,只能访问静态成员

      • 调用方式:ClassName::func()

四、类声明与定义

  1. 前向声明

    • 使用场景:解决循环依赖、减少头文件包含

    • 限制:只能定义指针/引用,不能访问成员

      class B; // 前向声明  
      
      class A {  
      public:  
          B* pb;        // 允许定义指针  
          void func(B&);  
      };  
      
      class B {  
      public:  
          A* pa;  
      };  
  2. 字面值常量类

    • 要求:

      • 所有成员都是字面类型

      • 至少一个constexpr构造函数

      • 成员初始值必须为常量表达式

        class ConstExprDemo {  
        public:  
            constexpr ConstExprDemo(int x) : val(x) {}  
            constexpr int getVal() const { return val; }  
        private:  
            int val;  
        };  
        
        int main() {  
            constexpr ConstExprDemo c(42);  
            int arr[c.getVal()]; // 用于编译期常量  
        }  
  3. 聚合类

    • 定义条件(C++17前):

      • 所有成员public

      • 无用户定义构造函数

      • 无基类、无虚函数

    • 初始化方式:MyClass obj = {val1, val2};

      // C++17前聚合类  
      struct Aggregate {  
          int id;  
          string name;  
      };  
      
      int main() {  
          Aggregate a = {1, "Alice"}; // 聚合初始化  
      }  

五、类的作用域

  1. 名字查找规则

    • 成员函数内名字查找顺序:局部作用域 → 类作用域 → 外围作用域

    • 类外定义成员函数时的作用域限定:ClassName::

      class ScopeTest {  
      public:  
          void func(int x) {  
              x = 0;       // 参数x隐藏成员变量  
              this->x = x; // 使用this访问成员  
          }  
      private:  
          int x{0};  
      };  
  2. 成员隐藏与覆盖

    • 局部变量隐藏成员变量:使用this->访问成员

    • 派生类成员隐藏基类同名成员

六、友元机制

  1. 友元类

    • 单向授权:友元类可访问当前类的私有成员

    • 典型应用:迭代器类访问容器私有数据

      class Storage {  
          friend class Logger; // 友元类  
      private:  
          string secret{"Confidential"};  
      };  
      
      class Logger {  
      public:  
          void log(const Storage& s) {  
              cout << s.secret; // 访问私有成员  
          }  
      };  
  2. 友元函数

    • 非成员友元函数:需在类内声明,类外定义

    • 友元成员函数:需注意声明顺序依赖

    class Window;  
    
    class Controller {  
    public:  
        void resetWindow(Window& w);  
    };  
    
    class Window {  
        friend void Controller::resetWindow(Window&);  
    private:  
        int state{0};  
    };  
    
    void Controller::resetWindow(Window& w) {  
        w.state = 0; // 访问Window私有成员  
    }  
  3. 友元的特性

    • 不可传递性:友元的友元不是我的友元

    • 不可继承性:基类友元不是派生类友元

七、类定义的两阶段处理

  1. 编译阶段划分

    • 第一阶段:处理成员声明(包括类型检查)

    • 第二阶段:处理成员函数体(此时类已完整定义)

      class TwoPhase {  
      public:  
          typedef int value_type;  
          value_type process() {  
              return data; // 正确:第二阶段处理函数体  
          }  
      private:  
          value_type data{0};  
      };  
  2. 影响场景

    • 成员函数体内可使用类后续声明的成员

    • 成员默认参数初始化顺序依赖

八、高级特性补充

  1. 拷贝控制成员

    • 拷贝构造函数、拷贝赋值运算符

    • 移动构造函数、移动赋值运算符(C++11)

    • 析构函数

      class String {  
      public:  
          String(const char* s);        // 构造函数  
          String(const String&);        // 拷贝构造  
          String& operator=(const String&); // 拷贝赋值  
          ~String() { delete[] data; }  // 析构函数  
      private:  
          char* data;  
      };  
  2. 成员函数特性

    • const成员函数:承诺不修改对象状态

    • 引用限定符(C++11):&&&限制调用对象的值类别

  3. 嵌套类与局部类

    • 嵌套类访问权限:遵循常规访问控制规则

    • 局部类限制:不能定义静态成员、不能访问非静态局部变量

九、设计模式关联

  1. RAII(资源获取即初始化)

    • 通过构造函数获取资源,析构函数释放资源

  2. PIMPL(Pointer to Implementation)

    • 使用不透明指针隐藏实现细节


知识图谱总结

核心概念关键要点C++11/17增强
构造函数家族默认/拷贝/移动/委托构造=default, 委托构造
封装与访问控制public/private/友元机制friend作用域优化
静态成员类内初始化、生命周期管理内联静态成员(C++17)
类型转换控制explicit关键字多参数explicit(C++20)
特殊类设计字面值常量类、聚合类聚合类扩展(C++17)


http://www.kler.cn/a/547557.html

相关文章:

  • SolidWorks速成教程P3-6【零件 | 第六节】——草图封闭轮廓所选轮廓厚度为零的报错
  • Unity Shader Graph 2D - Procedural程序化图形循环的箭头
  • openmv vs canmv 特征点检测 在线例程对比
  • python包的管理
  • 【第8章:深度学习框架与工具—8.1 TensorFlow与PyTorch的对比与选择建议】
  • 网页五子棋——用户模块
  • Vript-Hard——一个基于高分辨率和详细字幕的视频理解算法
  • TestHubo基础教程-创建项目
  • Python函数进阶250215
  • 从ARM官方获取自己想要的gcc交叉编译工具链接(Arm GNU Toolchain),并在Ubuntu系统中进行配置
  • 服务器模式部署mediacms后卸载mediacms,包括数据库
  • 项目版本号生成
  • CentOS 7上安装Python 3的步骤如下
  • 车规MCU处理器选择Cortex-M7还是Cortex-R52?
  • 树莓集团:从区域到全国,数字产业园服务如何有效赋能企业?
  • 【Erdas实验教程】004:影像镶嵌拼接
  • DeepSeek指导手册从入门到精通
  • 使用API有效率地管理Dynadot域名,清除某一文件夹中域名的默认DNS设置
  • 深度探索 DeepSeek:AI 领域的璀璨新星
  • Flutter_学习记录_网络请求的简单了解