虚函数

设计模式学习:基本原则

谁说我不能喝 提交于 2020-03-08 16:52:58
1.设计模式总览 1.1基本概念 模式就是一套被反复使用解决某一问题的方案,包括三个基本元素( 问题,解决方案,环境 ) 设计模式就是为了可重用代码,让代码更容易被他人理解,保证代码可靠性的一种经验总结。 设计模式的基础是多态。多态的原理是编译器为每一个含有虚函数的子类和父类提前布置了一个vptr指针,通过这个vptr指针找到一个虚函数表,根据虚函数表找到后来人写的代码去执行。 1.2分类 Design Patterns:Elements of Resualbel Software将设计模式归纳为以下3个大类 创造型模式:通常和对象的创建有关,设计到对象实例化的方式。(共5种模式) 结构性模式:描述的是如何组合类和对象以获得更大的结构。(共7种模式) 行为型模式:用来对类或对象怎样交互和怎样分配职责进行描述(共11种模式) 1.3基本原则 高内聚,低耦合 1)开放封闭原则: 类的改动是通过增加代码进行的,而不是修改源代码。 2)单一职责原则: 类的职责要单一,对外只提供一种功能,而引起类变化的原因都应该只有一个。 //以上两个原则可以举例如下,想要修改只需要增加新的代码而无需修改抽象父类 class AvBankWorker { public: virtual void dothing() = 0; private: }; class SaveBanker :public

C++面试题

时光怂恿深爱的人放手 提交于 2020-03-08 08:06:32
语言基础类 1. 指针和引用的区别? (1)指针有自己的一块空间,而引用只是一个别名;  (2)使用 sizeof 看一个指针的大小为 4 字节(32位,如果要是64位的话指针为8字节),而引用则是被引用对象的大小。 (3) 引用必须在定义时被初始化,指针不必; (4)不存在指向空值的引用,但存在指向空值的指针。 2.static和 const的用法,(能说出越多越好)(重点) 首先说说const的用法(绝对不能说是常数) 1.限定变量为不可修改。 2.限定成员函数不可以修改任何数据成员。 3.使用const关键字修饰的变量,一定要对变量进行初始化 下面的声明都是什么意思? const int a; a是一个常整型数 int const a; a是一个常整型数 const int *a; a是一个指向常整型数的指针,整型数是不可修改的,但指针可以 int * const a; a为指向整型数的常指针,指针指向的整型数可以修改,但指针是不可修改的 int const * a const; a是一个指向常整型数的常指针,指针指向的整型数是不可修改的,同时指针也是不可修改的 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。

C++虚函数实现

若如初见. 提交于 2020-03-07 03:08:51
虚函数出现的原因 C++多态通过虚函数来实现,虚函数允许子类重新定义成员函数,而子类重新定义父类的做法称为覆盖,或者称为重写。 最常见的用法就是声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,动态绑定。由于编写代码时不能确定被调用的是基类还是哪个派生类的函数,所以被称为“虚函数”。如果没有使用虚函数的话,即没有利用C++的多态性,则利用基类指针调用相应的函数时,总被限制在基类函数本身,而无法调用到子类中被重写过的函数。 # include <iostream> using namespace std ; class A { public : void foo ( ) { printf ( "A::foo()1\n" ) ; } virtual void fun ( ) { printf ( "A::fun 2\n" ) ; } } ; class B : public A { public : void foo ( ) //隐藏:派生类的函数屏蔽了与其同名的基类函数 { printf ( "B::foo3\n" ) ; } void fun ( ) //多态、覆盖 { printf ( "B::fun4\n" ) ; } } ; int main ( void ) { A a ; B b ; A * p = & a ; p - > foo ( ) ; //输出1

虚函数和模板的用途区别

半腔热情 提交于 2020-03-04 02:49:49
模板是范型编程的基础,所谓范型编程就是用独立与任何特定类型的方式编写代码 所以简单地说,类是对象的抽象,而模板又是类的抽象,也就用模板能定义出具体类 再理解深刻点 在c++里,常说的多态一般分为两种: 一种是运行时的多态,也就是虚函数体现的多态 另一种是编译时的多态,也就是范型编程的多态,体现在参数的多态 在作用上是为了提高编程效率,其实用其他技术也能达到同样的效果 另外贴一篇讲虚函数的存在意义的知乎回答,写的实在太清楚了: 作者:乌索普 链接:https://www.zhihu.com/question/23971699/answer/84332610 虚函数主要是用来实现多态和多重继承的 没有虚函数理论上也可以实现多态,但是太麻烦了,没有虚函数清晰 主要是在多态上使用。 多态是什么呢: 多态就是一个指针指向子类对象,那么他调用的函数就是子类的对象的。 这就实现了什么? 实现了一个函数会根据传入参数的不同有不同的功能。 函数有多个状态。 就是多态 void fuck (Animal *a); 如果没有多态 那么 这个函数 只能fuck Animal 想要fuck多种 就要用重载,写多个同名函数 参数不同 但是有了多态 他可以fuck所有Animal的子类 比如牛 羊 耗子 什么的 根据传进来的参数不同,fuck不同的动物。 这样这个函数就是fuckAnimalYouWant

C++虚函数与非虚函数的区别。

不打扰是莪最后的温柔 提交于 2020-03-03 16:59:29
#include <iostream> #include <string> /* * Animal 与Dog之间没有虚函数 * Animal Fish有一个eating的虚函数 * 通过"基类的指针" 访问 子类(们)的成员函数。这叫动态多态。是用虚函数的技术完成的。这也叫动态绑定。] * 当我们使用基类的引用(或指针)调用一个虚函数时将发生动态绑定(dynamic binding) 因为我们直到运行时才能知道到底调用了哪个版本的虚函数,可能是基类中的版本也可能是派生类中的版本,判断的依据是引用(或指针)所绑 定的对象的真实类型。 * 与非虚函数在编译时绑定不同,虚函数是在运行时选择函数的版本,所以动态绑定也叫运行时绑定(run-time binding)。 * * 虚函数的指针会保存到class里的"虚函数表"中。每一个对象都会一个自己的“虚函数表”。类似对函数指针列表。 * * */ using namespace::std; class Animal { public: string name; string attr; Animal(string n):name(n){}; Animal(string n,string a):name(n),attr(a){}; void runing(int i) { cout<<"animal("<<name <<") can

虚函数和纯虚函数

﹥>﹥吖頭↗ 提交于 2020-03-03 11:56:43
class A { public: virtual void foo() { cout<<"A::foo() is called"<<endl; } }; class B:public A { public: void foo() { cout<<"B::foo() is called"<<endl; } }; int main(void) { A *a = new B(); a->foo(); // 在这里,a虽然是指向A的指针,但是被调用的函数(foo)却是B的! return 0; }   上诉代码是虚函数的一个例子。其中B类继承A类,由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被成为"虚"函数。而虚函数只能借助于指针或者引用来达到多态的效果。 纯虚函数 一、定义: virtual void funtion1()=0   纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加"=0" 二、引入原因: 1、为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。 2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。   为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法

虚函数注意事项和多态构成条件

柔情痞子 提交于 2020-03-02 20:50:08
虚函数只需要在声明处加vitrual关键字,注意是声明处 为了方便,可以只将基类中的函数声明为虚函数,这样所有派生类中具有遮蔽关系的同名函数都将自动成为虚函数,多继承的时候需要小心。 当在基类中定义了虚函数时,如果派生类没有定义新的函数来遮蔽此函数,那么将使用基类的虚函数。 只有派生类的虚函数覆盖基类的虚函数(函数原型相同)才能构成多态(通过基类指针访问派生类函数) 构造函数不能是虚函数 析构函数可以声明为虚函数,而且**有时候必须要声明为虚函数 ** 基类虚函数重载,子类必须遮蔽时(即将父类的重载函数遮蔽)才会调用子类函数 //基类Base class Base { public : virtual void func ( ) ; virtual void func ( int ) ; } ; void Base : : func ( ) { cout << "void Base::func()" << endl ; } void Base : : func ( int n ) { cout << "void Base::func(int)" << endl ; } //派生类Derived class Derived : public Base { public : void func ( ) ; void func ( char * ) ; } ; void Derived

C++中四种强制类型转换区别详解

情到浓时终转凉″ 提交于 2020-03-02 13:22:19
 C++即支持C风格的类型转换,又有自己风格的类型转换。C风格的转换格式很简单,但是有不少缺点的:   1.转换太过随意,可以在任意类型之间转换。你可以把一个指向const对象的指针转换成指向非const对象的指针,把一个指向基类对象的指针转换成一个派生类对象的指针,这些转换之间的差距是非常巨大的,但是传统的C语言风格的类型转换没有区分这些。   2.C风格的转换没有统一的关键字和标示符。对于大型系统,做代码排查时容易遗漏和忽略。   C++风格完美的解决了上面两个问题。1.对类型转换做了细分,提供了四种不同类型转换,以支持不同需求的转换;2.类型转换有了统一的标示符,利于代码排查和检视。下面分别来介绍这四种转换:static_cast、dynamic_cast、const_cast和reinterpre_cast. 一、static_cast转换   1.基本用法:static_cast<type-id> expression   2.使用场景:   a、用于类层次结构中基类和派生类之间指针或引用的转换   上行转换(派生类---->基类)是安全的;   下行转换(基类---->派生类)由于没有动态类型检查,所以是不安全的。   b、用于基本数据类型之间的转换,如把int转换为char,这种带来安全性问题由程序员来保证   c、把空指针转换成目标类型的空指针   d

C++复习知识点总结(二)

独自空忆成欢 提交于 2020-03-02 01:15:28
一:C++多态与虚函数 1:基类的指针也可以指向派生类对象 People *p = new People(“王志刚”, 23) p = new Teacher(“赵宏佳”, 45, 8200);//指向派生类对象 调用函数时会出错(people的函数中没有第三项,及8200的数据),即当基类指针 p 指向派生类 Teacher 的对象时,虽然使用了 Teacher 的成员变量,但是却没有使用它的成员函数 基类指针只能访问派生类的成员变量,但是不能访问派生类的成员函数,C++ 增加了虚函数(Virtual Function)。使用虚函数非常简单,只需要在函数声明前面增加 virtual 关键字。即:virtual 类型 函数名 对于派生类比较多,如果不使用多态,那么就需要定义多个指针变量,很容易造成混乱;而有了多态,只需要一个指针变量 p 就可以调用所有派生类的虚函数。 2:虚函数注意事项及条件 虚函数对于多态具有决定性的作用,有虚函数才能构成多态。 只需要在虚函数的声明处加上 virtual 关键字,函数定义处可以加也可以不加。 基类中的函数声明为虚函数,这样所有派生类中具有遮蔽关系的同名函数都将自动成为虚函数 只有派生类的虚函数覆盖基类的虚函数(函数原型相同)才能构成多态(通过基类指针访问派生类函数)。例如基类虚函数的原型为virtual void func();

C++复习小知识点总结

ぐ巨炮叔叔 提交于 2020-03-01 11:55:50
一:C++纯虚函数和抽象类详解 1:在C++中,可以将虚函数声明为纯虚函数,语法格式为: virtual 返回值类型 函数名 (函数参数) = 0; 最后的=0并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是纯虚函数”,包含纯虚函数的类称为抽象类 抽象类通常是作为基类,让派生类去实现纯虚函数。派生类必须实现纯虚函数才能被实例化 一个纯虚函数就可以使类成为抽象基类,但是抽象基类中除了包含纯虚函数外,还可以包含其它的成员函数(虚函数或普通函数)和成员变量。 只有类中的虚函数才能被声明为纯虚函数,普通成员函数和顶层函数均不能声明为纯虚函数 二:typeid运算符:获取类型信息 typeid 运算符用来获取一个表达式的类型信息。 来源: CSDN 作者: weixin_45800159 链接: https://blog.csdn.net/weixin_45800159/article/details/104573007