运算符重载与虚函数

单目运算符

接下来都以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++没有接口功能,那么这个纯虚函数便是用作接口功能
  • 底下的派生类只有将所有纯虚函数全部实现才能称之为_具体类_
  • 也可以用另一种观点来看,就是为所有派生类定义了规范
  • 这是一种面向接口的设计方式,也是面向抽象类的设计
  • 抽象类的设计需要非常谨慎,因为派生类需要围绕抽象类进行设计
  • 那么如果没有设计好抽象类,那么容易带偏派生类
几个小规定
  • 抽象类只能用作基类
  • 不能声明抽象类的对象
    • 原因:抽象类中具有纯虚函数,而这个函数按语法可调用,但是这个函数没有实现,因而为了解决这个问题直接禁止了抽象类的声明
  • 构造函数不能够是虚函数,析构函数可以是虚函数
  • 可以定义抽象类的指针

c++运算符重载和虚函数的更多相关文章

  1. C++多态性----运算符重载与虚函数

    一.多态性 ①概述:多态是指同样的消息被不同类型的对象接收时导致的不同行为. ②类型: 可以分为四类:重载多态.强制多态.包含多态.参数多态. ------------------------ --- ...

  2. c++入门之—运算符重载和友元函数

    运算符重载的意义是:将常见的运算符重载出其他的含义:比如将*重载出指针的含义,将<<与cout联合使用重载出输出的含义,但需要认识到的问题是:运算符的重载:本质仍然是成员函数,即你可以认为 ...

  3. C++运算符重载(友元函数方式)

    我们知道,C++中的运算符重载有两种形式:①重载为类的成员函数(见C++运算符重载(成员函数方式)),②重载为类的友元函数. 当重载友元函数时,将没有隐含的参数this指针.这样,对双目运算符,友元函 ...

  4. C++继承-重载-多态-虚函数

    C++ 继承 基类 & 派生类 一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数.定义一个派生类,我们使用一个类派生列表来指定基类.类派生列表以一个或多个基类命名,形式如下: ...

  5. C++ 派生类函数重载与虚函数继承详解

    目录 一.作用域与名字查找 1.作用域的嵌套 2.在编译时进行名字查找 3.名字冲突与继承 4.通过作用域运算符来使用隐藏的成员 二.同名函数隐藏与虚函数覆盖 1.几种必须区分的情况 2.一个更复杂的 ...

  6. 【C++】多态性(函数重载与虚函数)

    多态性就是同一符号或名字在不同情况下具有不同解释的现象.多态性有两种表现形式: 编译时多态性:同一对象收到相同的消息却产生不同的函数调用,一般通过函数重载来实现,在编译时就实现了绑定,属于静态绑定. ...

  7. C++抽象编程·运算符重载与友元函数

    运算符重载(Operator overloading) 从我们在几个前篇的类的层次介绍中可以知道,C++可以扩展标准运算符,使其适用于新类型.这种技术称为运算符重载. 例如,字符串类重载+运算符,使其 ...

  8. C++运算符重载形式——成员函数or友元函数

    运算符重载是C++多态的重要实现手段之一.通过运算符重载对运算符功能进行特殊定制,使其支持特定类型对象的运算,执行特定的功能,增强C++的扩展功能. 运算符重载的我们需要坚持四项基本原则: (1)不可 ...

  9. C++运算符重载(成员函数方式)

    一.运算符重载 C++中预定义的运算符的操作对象只能是基本数据类型,实际上,对于很多用户自定义类型,也需要有类似的运算操作.如果将C++中这些现存的运算符直接作用于用户自定义的类型数据上,会得到什么样 ...

随机推荐

  1. 将GPT转换成MBR

    准备一个pe启动盘 1.单击”运行“在弹出来的窗口输入cmd回车 2.在输入“diskpart”回车 3.在输入“list disk”显示硬盘信息,查看那个盘是gpt分区类型 4.输入“select ...

  2. web应用框架Django

    一.安装Django 打开网址https://www.djangoproject.com/download/进行查看 二.创建项目 打开命令行,进入想要安置项目的目录 命令行输入:django-adm ...

  3. 性能测试学习第十天_controller

    集合点设置 controller虚拟多个用户执行脚本启动步骤不一定同步,集合点在脚本的某处设置一个标记,当有虚拟用户运行到这个标记的时候,停下等待所有用户都达到这个标记,再一同进行下面的步骤.这样可以 ...

  4. hibernate课程 初探单表映射1-8 hibernate持久化类

    java beans 的设计原则 1 公有的类 2 共有不带参数构造方法 3 私有属性 4 属性setter/getter方法 Studnet类: package com.ddwei.student; ...

  5. hibernate课程 初探单表映射1-3 hibernate简介

    1 hibernate定义: Java领域一项开源的orm框架技术: hibernate对jdbc进行轻量级的封装. hibernate 作为持久层存在.就是通过对象关系映射把项目中的对象持久化到数据 ...

  6. 使用纯css实现波浪效果

    有时候我们需要实现水晃动的效果,其实我们可以通过css旋转动画和圆角来实现. 首先来2个div,外层div相对定位,内层div绝对定位,内层div大致位于外层div上半部分.外层div设置一个颜色较深 ...

  7. JSP对象和JavaBean

    1. JSP 客户端请求 当浏览器请求一个网页时,它会向网络服务器发送一系列不能被直接读取的信息,因为这些信息是作为HTTP信息头的一部分来传送的,如下图所示: Http请求头对应的内容如下: 对应方 ...

  8. nginx停止后再启动出现: [error] open() "/usr/local/nginx/logs/nginx.pid" failed错误的解决方法

    为了备份数据 手动停止了服务器的nginx 结果启动时报错 nginx: [error] open() "/usr/local/nginx/logs/nginx.pid" fail ...

  9. 私有npm下载资源

    私有npm库下载资源需要用户名和密码,这个需要创建npm库的人提供. 使用方法: npm login --registry=仓库地址 Username: 用户名 Password: 密码 Email: ...

  10. HTML 笔记之 HTML 元素的概念

    HTML 不是编程语言,它是一种标记语言 HTML 中常见的几个名词是 元素. 标签(开始标签和结束标签). 属性. 元素内容 这篇文章将要介绍的是 HTML 元素的概念 元素的概念 例子: < ...