【C++】类封装和继承设计

数据抽象

类的基本思想是数据抽象 data abstraction
封装后的类分离了 interface 和 implementation,具体实现时通常都按照分离式编译的原则,在 .h 声明和 .cpp 实现

  • 定义类
    类本身就是个作用域,类的成员函数定义嵌套在类的作用域中,因此类的成员函数可以直接使用类的数据成员,即使该数据成员定义在函数之后。
    不能在类中定义类对象(类未定义完,无法确定类对象存储空间)

  • 构造函数
    初始化类对象的数据成员。未声明任何构造函数时,编译器会自动生成默认构造函数。
    初始化方式: 类内(构造函数外)初始化、构造函数初始值列表、构造函数体内部的赋值操作 以及 默认初始化

  • 成员函数
    类内定义的函数为自动 inline
    类内部显式声明 inline,类外的函数定义必须在同一头文件(通常用.inl文件)

    成员函数可通过 this 访问调用该函数的类对象,此时this为 指向非常量类对象的常量指针 object *const,指针本身为常量
    成员函数参数列表后带const,则修改this为 指向常量类对象的常量指针 const object *const,即函数内部不能改变类对象的内容

  • static 静态变量及静态函数
    类对象中不包含任何静态成员的相关数据。静态成员存在于任何对象之外。
    static变量不是由构造函数初始化的(即不是创建类对象时初始化)
    静态成员函数也不与任何对象绑定在一起(不使用this指针,不能声明为const)

  • 拷贝、赋值和析构

类的访问控制

  • 访问说明符 public、private
    class默认成员为private,struct默认成员为public

  • 友元
    有时候需要封装类的数据成员,同时也需要为一部分非类成员函数开放访问权限。

    友元允许其他类或函数访问其非公有成员,有三种实现方式:
    将其他类当作友元 class Name { friend class FriendName; }
    将辅助函数(非成员函数)当作友元 class Name{ friend returnType func(params); } 内部声明表示友元函数对该类有访问权限,但该声明不是函数本身的声明,它自身应有另外的专门声明
    将其他类的一个成员函数当作友元 但这种方式需要要特别注意顺序

    class OtherName {  returnType func(...);  }
    // 需首先定义其他类,完成作为友元函数的类成员函数的声明
    // 但不能进行函数定义,因为没法使用Name的数据(还没定义)
    
    class Name {  friend returnType OtherName::func(params);  }	 // 声明友元
    returnType OtherName::func(params){...}                      // 友元函数定义
    

继承

  • 派生类的成员
    继承 + 自身定义(两部分不一定连续存储 )

  • 访问权限
    派生类 继承了定义在基类中的全部成员(不论私有保护公有),只是不一定有访问权限
    派生类定义时的访问说明符,决定了 派生类对象(以及派生类的派生类)是否有权限访问继承的基类成员

    protected成员在派生类的成员函数中 只能通过this访问(而不是通过基类对象访问,因为没有,本质在访问自己继承下来的基类部分)
    protected成员不能通过派生类对象访问

    class Base {
    	returnType func(..);           // 直接继承不改变
    	virtual returnType func(...);  // 希望被重写的
    
    public:
    
    private:  // 基类成员和友元可访问,基类对象不可访问
    	 	  // 派生类成员不可访问
    	  
    protected:  // 基类成员和友元可访问,基类对象不可访问 private
    	    	// 派生类成员可访问 public
    	    	// 派生类对象是否可访问,与定义派生类时的访问控制符相关
    }
    
    class Derived : public Base {
    	Derived(...) : Base(..), mem(){}
    }
    
  • 虚函数
    通过 virtual 关键字,基类将 类型相关函数派生类不做改变直接继承的函数 区分对待
    基类的析构函数必须为虚函数
    要求 所有虚函数必须有定义(包括基类和派生类),这样运行时才能调用对应版本

    虚函数函数体 =0纯虚函数(避免具体定义)
    包含虚函数的类为 抽象基类

  • final 和 override 关键字

动态绑定 run-time binding

多态 polymorphism 的根本设计原则在于 引用、指针的静态类型和动态类型可以不相同(非引用、指针类其动态与静态类型一致)

静态类型:编译时已知,声明时对象的类型
动态类型:运行时才可知,内存中对象的类型

  • 派生类到基类的隐式转换
    派生类对象含有与基类对应的部分,因此能把派生类对象当作基类对象使用。即能将基类的指针和引用绑定到派生类对象的基类部分
    基类向派生类不存在隐式类型转换

  • 实现动态绑定的条件
    使用基类对象的引用或指针调用虚函数。而当通过普通类型的表达式(非指针非引用)调用虚函数,编译时就会把使用版本确定下来。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值