操作符重载、继承(day08)

二十 操作符重载
5 函数操作符"()"
功能:让对象当做函数来使用
注:对参数的个数、返回类型没有限制
eg:
class A{...}; 
A a;
//a.operator()(100,200)
a(100,200); 
 
 
6 下标操作符"[]"
功能:让对象可以当做数组一样去使用
注:非常对象返回左值,常对象返回右值
eg:
string s("hello");
//s.operator[](0)
s[0] = 'H';//ok
cout << s << endl;//Hello
-------------
const string s("hello");
s[0] = 'H';//error

7 类型转换操作符
功能:实现自定义类型的转换
class 源类型{
   operator 目标类型(void)const{...}
};

8 操作符重载的限制
1)不是所有的操作符都能重载,下面几个不能重载
--》作用域限定操作符 "::"
--》直接成员访问操作符 "."
--》直接成员指针解引用操作符 ".*"
--》条件操作符 "?:"
--》字节长度操作符 "sizeof"//获取类型大小
--》类型信息操作符 "typeid"//获取类型信息(后面讲)
2)如果一个操作符的所有操作数都是基本类型,则无法重载。
   int operator+(int a,int b){//error
       return a - b;
   }
3)操作符重载不会改变编译器预定义优先级
4)操作符重载无法改变操作数的个数(函数操作符例外)
5)无法通过操作符重载机制发明新的的操作符
  operator@()//error
6)只能使用成员形式不能使用全局函数形式的操作符
 =、()、[]、->

===================
二十一 继承(Inheritance)
1 继承的概念
  通过一种机制表达类与类之间共性和特性的方式,利用已有的类定义新的类,这种机制就是继承。

eg:描述人类、学生类、教师类
人类:姓名、年龄、吃饭、睡觉
学生类:姓名、年龄、吃饭、睡觉、学号、学习
教师类:姓名、年龄、吃饭、睡觉、工资、讲课
-------------
人类:姓名、年龄、吃饭、睡觉
学生类继承人类:学号、学习
教师类继承人类:工资、讲课

   人类(父类/基类)
  /     
学生类  教师类(子类/派生类)

2 继承的语法
1)定义
  class 子类名
    :继承方式1 基类1,继承方式2 基类2,...{};
2)继承方式
  public:公有继承
  protected:保护继承
  private:私有继承
  
  eg:
  class A{...};
  //A类派生B类,B类继承A类
  //A类称为基类(父类),B称为子类
  class B:public A{
      //B类中会存在一份A类中的成员
  };
  
3 公有继承特性(Public)
3.1 子类对象可以继承基类的属性和行为,通过子类访问基类中的成员,如果是基类对象在访问它们一样。
注:子类对象中包含基类的部分称为"基类子对象"

3.2 向上和向下造型
1)向上造型//重点掌握
   将子类类型的指针或引用转换为基类类型的指针或引用。这种操作范围缩小的类型转换,在编译器看来是安全的,所以可以隐式转换。
eg:
   class Base{};
   class Derived:public Base{};
   void func(Base& b){}
   int main(void){
           Derived d;
           Base* pb = &d;//向上造型
           Base& rb = d;//向上造型
           func(d);//向上造型
   }
2)向下造型//了解
   将基类类型指针或引用转换为子类类型的指针或引用。这种操作范围放大的类型转换,在编译器看来是危险的,因此必须显式转换。
   
3.3 子类继承的基类成员
1)在子类中,可以直接访问基类中公有成员和保护成员,就如同它们是子类自己的成员一样。
2)在子类中,所继承过来的私有成员虽然存在(占据内存),但是不可见,所以无法直接访问,但是可以提供保护或公有的接口函数来间接访问。
3)基类的构造函数和析构函数,子类无法继承,但是可以在子类自己的构造函数中通过初始化表,显式的指明基类部分(基类子对象)的初始化方式。
eg:
class Base{
public:
    Base(int data):m_data(data){}
    int m_data;
};
class Derived:public Base{
public:
    Derived(int data1,int data2)
        :Base(data1),m_data2(data2){}
    int m_data2; 
};

3.4 子类隐藏基类中的成员
1)子类和基类中定义同名的成员函数,因为作用域不同,不会构成重载关系,而是一种隐藏关系。如果需要在子类中访问所隐藏的基类成员,可以使用作用域限定操作符来显式指明。
2)通过using声明可以将基类的成员函数引入子类的作用域的,形成重载。//不推荐

4 继承方式和访问控制属性
1)三种访问控制限定符:影响访问该类成员的位置
访问控制            访问控制            内部    子类    外部     友元
限定符        属性                访问    访问    访问     访问
public        公有成员            ok      ok             ok      ok
protected            保护成员            ok      ok           no      ok
private        私有成员            ok      no             no      ok
---------------------------------------------
2)三种继承方式:影响通过子类访问基类中的成员的可访问性。
---------------------------------------------
基类中的      在公有子    在保护子         在私有子
      类中变成    类中变成         类中变成
公有成员      公有成员    保护成员         私有成员
保护成员      保护成员    保护成员         私有成员
私有成员  私有成员     私有成员         私有成员
----------------------------------------------
注:私有子类和保护子类的指针或引用,不能转换为其基类类型的指针或引用(不能向上造型).

练习:复习公有继承的语法特性
原文地址:https://www.cnblogs.com/Kernel001/p/7729869.html