c++运算符重载和虚函数

运算符重载与虚函数

单目运算符

接下来都以AClass作为一个类例子介绍

AClass{

int var

}

  • 区分后置++与前置++
  • AClass operator ++ () ++前置 一般设计为返回引用 这样的话可以将其作为左值(自然也可以作为右值,会调用该类的拷贝构造函数) ++class = ...
  • AClass operator ++ (int) 后置++ 一般设计返回一个旧的类 获得的是历史版本,所含有的int形参是用作区分类型的,并无实际含义
  • 由于一个__单变量__的构造函数可被视为__强制类型转换函数__
多目运算符
  • AClass & operator (const & Aclass a){ ... }

  • 因此如果该类的构造函数满足把int变成这个类,你甚至可以这么写

  • int a; AClass A; A = A + a

函数的默认形参值只能写在声明里,不能写在定义里

  • 对于<< 的重载方式,定义友元函数
  • frend ostream & operator << (ostream & out, const ...)
  • 这样ostream就能访问该类的私有成员了
  • 注意!插入运算符<< 的返回值要是这个out的引用
  • {... return & out} 这样就可以实现一直<<插入的神奇功能(请自己思考为什么, 提示:返回引用等于又把自己拿出来用了)

虚函数

覆盖 override 重载 overload

虚函数基本语法

巧妙的覆盖方式

  • 虚函数的声明
  • virtual 函数类型 函数名(形参表){
  • 函数内容}
  • 可以在基类中声明虚函数,则子类中的相关函数会被同样被认为为虚函数
  • 并且在创建基类指针指向一个子类时
  • 调用该基类指针的这个虚函数
  • 该指针会顺着找到子类的这个函数并且运行
  • 体现了程序运行过程中的__动态多态特性__
  • 例子
class Base{
    virtual void func(){
        cout << "Base" << endl;
    }
}
class Base1{
    void func(){
        cout << "Base1" << endl;
    }
}
class Base2: public base{
    void func(){
        cout << "Base2" << endl;
    }
}
void display(base * ptr)
int main(){
    Base1 b1;
    Base2 b2;
    Base * ptr1 = b1;
    Base * ptr2 = b2;
    display(ptr1);
    display(ptr2);
}

/*
输出结果
Base1
Base2

*/

typeid

  • typeid(ptr).name() 此处ptr为一个指针,返回这个指针的类型
  • typeid(* ptr).name() 此处返回的是ptr指向对象的类型
  • 如果你对上面的ptr1 ptr2进行第一种操作返回类型为base
  • 但是如果做第二种操作返回是base1和base2
虚析构函数

可能你想不到,析构函数也很虚

  • 析构函数和构造函数是不会继承的
  • 加上析构函数在组合关系中会按拓扑序反向调用
  • 那么要虚构函数的理由就是有时候你需要动态删除由__基类指针指向的派生类__
  • 没有虚函数你就只能把指针指向的东西__当成基类__,而其本身是__派生类__,进行了析构
  • 那么这样子你就会漏去除一些内容
  • 这样很不优雅(你可以想象内存会出现什么严重后果)
举个栗子!
  • 比如我这么引用Base *b = new Derived()

derived 代指派生类

  • 那么我们的b一调用delete就凉凉了
  • delete b
  • 编译器高兴地把b指向的地方当做Base删掉了
  • 仔细想想,Derived的构造函数被调用了,但是析构函数被忽略了,(原因是我换了一个指针引用)
解决方法(就是虚析构函数)
  • 给基类的析构函数前面加个virtual关键字
  • 那么这就给这个东西加上了__动态多态性!__
  • 然后编译器就会跑去先调用一下Derived类的析构函数然后再调用Base的

纯虚函数

很纯洁的函数

  • 想想,概念都是完美的东西,那么纯虚函数就是用来描述概念的
纯虚函数语法
  • virtual 类型 函数名(参数列表) = 0
  • 正如你所见,它没有函数体(非常的纯)
  • 带有纯虚函数的类称之为__抽象类__(另一个叫做__具体类__)
抽象类
概念及理念
  • 为啥需要抽象类
  • 由于c++没有接口功能,那么这个纯虚函数便是用作接口功能
  • 底下的派生类只有将所有纯虚函数全部实现才能称之为_具体类_
  • 也可以用另一种观点来看,就是为所有派生类定义了规范
  • 这是一种面向接口的设计方式,也是面向抽象类的设计
  • 抽象类的设计需要非常谨慎,因为派生类需要围绕抽象类进行设计
  • 那么如果没有设计好抽象类,那么容易带偏派生类
几个小规定
  • 抽象类只能用作基类
  • 不能声明抽象类的对象
    • 原因:抽象类中具有纯虚函数,而这个函数按语法可调用,但是这个函数没有实现,因而为了解决这个问题直接禁止了抽象类的声明
  • 构造函数不能够是虚函数,析构函数可以是虚函数
  • 可以定义抽象类的指针
原文地址:https://www.cnblogs.com/Phoenix-blog/p/9073823.html