虚函数

纯虚函数与抽象类

最后都变了- 提交于 2019-12-02 12:40:25
纯虚函数与抽象类 一、纯虚函数 什么是纯虚函数? 纯虚函数是在基类中定义的一个虚函数,它在基类中没有具体的操作内容,是要在派生类中根据各自的需求定义。其声明格式为 virtual 函数类型 函数名(参数表)=0 为什么要用纯虚函数? 对于一些函数,需要在不同的派生类中用来执行相同类型操作来建立联系,那么就会想到虚函数,在基类中将其定义为虚函数,派生类中定义将基类的覆盖,通过基类的指针调用,就会起到此效果。但是,虚函数是需要在基类中定义,并要有具体的操作内容声明,而对于一些基类无法给出有意义的实现时,用虚函数就不知道该如何处理。纯虚函数就可以实现这一功能。代码一: 、、、 #include<iostream> using namespace std; class Base1 { public:virtual void display() const = 0;//设置纯虚函数 }; class Base2 :public Base1 { public:void display()const; }; void Base2::display()const { cout << "Base2::display()" << endl; } class Derived :public Base2 { public:void display()const; }; void Derived:

C++多态小结

眉间皱痕 提交于 2019-12-02 12:34:52
C++ 多态 多态 多态 按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。 C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。 多态与非多态的实质区别就是函数地址是早绑定还是晚绑定 。如果函数的调用,在编译器编译期间就可以确定函数的调用地址,并生产代码,是静态的,就是说地址是早绑定的。而如果函数调用的地址不能在编译器期间确定,需要在运行时才确定,这就属于晚绑定。 下面的实例中,基类 Shape 被派生为两个类,如下所示: #include <iostream> using namespace std; class Shape { protected: int width, height; public: Shape( int a=0, int b=0){ width = a; height = b; } int area(){ cout << "Parent class area :" <<endl; return 0; } }; class Rectangle: public Shape{ public: Rectangle( int a=0, int b=0):Shape(a, b) {} int area (){ cout << "Rectangle class area :" <<endl; return

对象模型

眉间皱痕 提交于 2019-12-02 12:29:36
对象模型 ​ 当一个类本身定义了虚函数,或其父类有虚函数时,为了支持多态机制,编译器将为该类添加一个虚函数指针(vptr)。虚函数指针一般都放在对象内存布局的第一个位置上,这是为了保证在多层继承或多重继承的情况下能以最高效率取到虚函数表。当vprt位于对象内存最前面时,对象的地址即为虚函数指针地址。发生动态绑定时,编译器根据虚指针找到相应的虚函数来执行。 ​ 非静态数据成员被配置在每一个类对象之内,静态数据成员、静态和非静态函数被放在类对象之外。虚函数则由下面两个步骤支持: 每个类产生出一堆指向虚函数的指针,放在虚表vptl中。 每个类对象被安插一个虚指针vptr,指向相关的虚表vptl。vptr的设置与重置有每一个类的构造函数、析构函数和拷贝复制运算符自动完成。 来源: https://www.cnblogs.com/vlyf/p/11745382.html

多态(第五次作业)

走远了吗. 提交于 2019-12-02 12:26:03
多态: 按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。 C++ 多态意味着 调用成员函数 时,会根据调用函数的对象的类型来 执行不同的函数。 有例子如下: #include<iostream> using namespace std; class Shape { protected: int width,height; public: Shape(int a = 0,int b = 0) { width = a; height = b; } int area() { cout << "Parent class area : " << endl; return 0; } }; class Rectangle : public Shape { public: Rectangle(int a = 0,int b = 0):Shape(a,b){} int area() { cout << "Rectangle class area : " << endl; return (width*height); } }; class Triangle: public Shape { public: Triangle(int a = 0,int b = 0):Shape(a,b){} int area() { cout << "Triangle class

C++多态

老子叫甜甜 提交于 2019-12-02 11:58:32
**C++的多态性用一句话概括就是**:在基类的函数前加上virtual关键字,<font color="red">在派生类中重写该函数</font>,运行时将会<font color="red">根据对象的实际类型来调用</font>相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数 1:用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数。 2:存在虚函数的类都有一个一维的虚函数表叫做虚表,类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的。 3:多态性是一个接口多种实现,是面向对象的核心,分为类的多态性和函数的多态性。 4:多态用虚函数来实现,结合动态绑定. 5:纯虚函数是虚函数再加上 = 0; 6:抽象类是指包括至少一个纯虚函数的类。 纯虚函数:virtual void fun()=0;**即抽象类!必须在子类实现这个函数,即先有名称,没有内容,在派生类实现内容。** 我们先看个例子 ``` #include "stdafx.h" #include <iostream> #include <stdlib.h> using namespace std; class Father { public: void Face() { cout << "Father's face" << endl; }

C++第五次作业

隐身守侯 提交于 2019-12-02 11:55:21
重载与多态 多态: 一、概念:指同样的消息被不同类型的对象接收时导致的不同行为。消息是指对类的成员函数的调用,不同的行为指不同的实现,也是调用了不同的函数。 二、类型: 重载多态、强制多态 (专用多态) 、 包含多态、参数多态 (通用多态) 。 三、多态的实现: 1、编译时的多态是在编译过程中确定了同名操作的具体对象。 2、运行时的多态是在程序运行过程中才动态地确定操作所针对的具体对象。 运算符重载: 是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同行为。 实质就是函数重载!!! 一、运算符的重载形式: 1、重载为类的非静态成员函数。 2、重载为非成员函数。 二、语法形式: 返回类型 operator 运算符(形参表) { 函数体 } 例:通过运算符重载实现复数类加减法。 #include<iostream> using namespace std; class Complex { public: Complex(double r = 0.0, double i = 0.0) :real(r), imag(i) {} Complex operator+(const Complex& c2)const; Complex operator-(const Complex& c2)const; void display()const; private:

C++第五次作业

不羁的心 提交于 2019-12-02 11:48:30
多态性 一、运算符重载 运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。 1、运算符重载的规则 (1)C++种的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已经有的运算符。 (2)重载之后的运算符的优先级和结核性都不会改变。 (3)运算符重载时针对新类型数据的实际需要,对原有运算符进行适当的改造。一般来讲,重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。 C++标准规定,有些操作符是不能重载的,它们是类属关系运算符"."、成员指针运算符".*"、作用域分辨符"::"和三目运算符"?:"。 前面两个运算符保证了C++中访问成员功能的含义不被改变。作用域分辨符的操作是类型,而不是普通的表达式,也不具备重载的特征。 运算符的重载形式: 返回类型 operator 运算符(形参表) {   函数体 } 重载为类的成员函数和重载为非成员函数的声明方式不同。 2、运算符重载的实例 对类Point重载“++”(自增)、“--”(自减)“、运算符,要求同时重载前缀和后缀的形式 #include <iostream> using namespace std; class Point { public: Point(int xx = 0, int yy = 0):x(xx),y(yy){}

C++ 第五次作业 重载与多态

安稳与你 提交于 2019-12-02 11:44:25
重载与多态 一、教学目标 熟练了解并掌握重载和多态的相关概念,进而在平时应用到,并且能了解其中的思想和过程 二、教学过程 (一)定义 多态是指同样的消息被不同类型的对象接收时导致的不同的行为,消息是指对类的成员函数的调用,不同的行为是指不同的实现,也就是调用了不同的函数。。 C++支持的多态有多种类型,重载(包括函数重载和运算符重载)和虚函数是其中 主要的方式。 (二)多态的类型 面向对象的多态性可以分为4类:重载多态,强制多态,包含多态和参数多态,前面两种称为专用多态,后面两种称为通用多态。 (三)多态的实现 分为两类:编译时的多态和运行时的多态。 (四)具体应用: 1.运算符重载: 运算符重载就是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。 运算符重载的本质就是函数重载。 注:运算符重载为类型的成员函数时,函数的参数个数比原来的操作个数要少一个;(后置++;- -除外) 重载为非成员函数时,个数相同。 举例:定义计数器 Counter 类,对其重载运算符 + typedef unsigned short USHORT; #include <iostream.h> class Counter { public: Counter(); Counter(USHORT initialValue); Counter(){} USHORT

C语言中的4种强制类型转换!

半世苍凉 提交于 2019-12-02 11:39:35
前言 在C语言中,我们需要做类型转换时,常常就是简单粗暴,在C++中也可以用C式强制类型转换,但是C++有它自己的一套类型转换方式。 C式的显示类型转换 先来说说C式的强制类型转换,它的用法非常简单,形如下面这样 Type b =111; Typea a = (Typea)b; 只需要用括号将你要转换的类型扩起来,放在要转换的变量前面即可。 举个例子: #include<stdio.h> intmain(void) { inta =0x01020304; char*b = (char*)&a; inti =0; for(;i <4;i++) { printf("%02x\n",b[i]); } return0; } 编译运行输出结果: 04 03 02 01 如果你好奇为什么会是这样的结果,请参考 《字节序的那些事》 。 C++ 四种强制类型转换。 当然,C++也是支持C风格的强制转换,但是C风格的强制转换可能带来一些隐患,让一些问题难以察觉.所以C++提供了一组可以用在不同场合的强制转换的函数。 const_cast , static_cast , dynamic_cast , reinterpret_cast const_cast 常量指针被转化成非常量的指针,并且仍然指向原来的对象; 常量引用被转换成非常量的引用,并且仍然指向原来的对象; const_cast一般用于修改指针

C++第五次作业

你。 提交于 2019-12-02 11:32:20
虚函数 虚函数是面向对象编程函数的一种特定形态,是C++用于实现多态的一种有效机制。 1、什么是虚函数? 指向基类的指针在操作它的多态类对象时,会根据不同的类对象调用其相应的函数,这个函数就是虚函数,虚函数用virtual修饰函数名。虚函数的作用是在程序的运行阶段动态地选择合适的成员函数。在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参类型,(参数类型的顺序也要一致),以实现统一的接口。如果在派生类中没有重新定义虚函数,则它继承基类的虚函数。 使用虚函数时需要注意一下几个方面: (1)只需在声明函数的类体中使用关键字virtual将函数声明为虚函数,在定义函数时不需要 (2)将基类中某一成员函数声明为虚函数后,派生类中的同名函数自动成为虚函数 (3)如果类(基类和派生类)中声明了某成员函数为虚函数,则类中不能再出现与之相同的非虚函数 (4)非类的成员函数不能定义为虚函数,全局函数以及类的静态成员函数(因为调用类的静态成员函数不需要实例,但调用虚函数需要一个实例)和构造函数(因为构造函数是在对象完全构造之前运行的,构造函数是初始化虚表指针,而当要调用虚函数时需要知道虚表指针,存在矛盾,但构造函数里是可以调用虚函数的)、内联函数也不能定义为虚函数,但一般将析构函数定义为虚函数(如果不把析构函数定义为虚函数,当用基类指针delete时,无法调用派生类的析构函数