虚函数

C++ 虚函数表与多态 —— 关键字 override 的用法

主宰稳场 提交于 2020-03-30 01:51:13
override 仅能用于虚函数,他属于C++新特性,是重写覆盖的意思,他的存在仅仅是为了提高代码的可阅读性: 作用: 1. 提示程序的阅读者,这个函数是重写父类的功能。 2. 防止程序员在重写父类的函数时,把函数名写错。 如下代码: 1 #include <iostream> 2 3 using namespace std; 4 5 class Class_1 6 { 7 virtual void func() 8 { 9 cout << "AAA" << endl; 10 } 11 12 }; 13 14 class Class_2 :public Class_1 15 { 16 void func() override //方法后加 override,可以方便程序员阅读代码,知道这方法是重写的,不用回去找 17 { 18 cout << "BBB" << endl; 19 } 20 }; 再比如: 1 #include <iostream> 2 3 using namespace std; 4 5 class Class_1 6 { 7 virtual void func() 8 { 9 cout << "AAA" << endl; 10 } 11 12 }; 13 14 class Class_2 :public Class_1 15 { 16 void func_1()

C++ 虚函数表与多态 —— 关键字 final 的用法

≯℡__Kan透↙ 提交于 2020-03-30 01:44:21
final 字面上最终、最后、不可改变的意思,final 这个关键字在 Jave PHP C++中都有用到,其作用也基本一致。 C++中的 final 是C++11新增,他可以用来修饰类,让类无法被继承;或用来修饰类的虚函数,让虚函数在子类中不能被重写。 final 只能修饰 类 与 虚函数,无法修饰普通成员函数。 一、 在类的继承关系中 final 的用法,让类无法被继承: 1 #include <iostream> 2 3 using namespace std; 4 5 class Class_1 final //可以再一开始就修饰 final 6 { 7 8 }; 9 10 class Class_2 final :public Class_1 //报错:不能将 final 类用作基类 11 { 12 13 }; 14 15 class Class_3 :public Class_2    //报错:不能将 final 类用作基类 16 { 17 18 }; 二、 虚函数禁止重写的 final 的方法,让虚函数在子类中不能被重写:   这种情况,可以继承,可以使用,只是不能够重写。 1 #include <iostream> 2 3 using namespace std; 4 5 class Class_1 6 { 7 virtual void func() final

C++ 多态及C和C++的区别

孤者浪人 提交于 2020-03-22 18:20:52
C和c++大的区别: c是面向过程的,数据与算法分开。它的重点在于算法和数据结构。侧重于计算机底层操作。 c++是面向对象的,主要特点是类,封装和继承。与C的区别主要为 :类、继承和多重继承、运算符重载、类模板、C++标准库、模板库。 C++是C的超集,也可以说C是C++的子集,因为C先出现。按常理说,C++编译器能够编译任何C程序,但是C和C++还是有一些小差别。 例如C++增加了C不具有的关键字。这些关键字能作为函数和变量的标识符在C程序中使用,尽管C++包含了所有的C,但显然没有任何C++编译器能编译这样的C程序。 C程序员可以省略函数原型,而C++不可以,一个不带参数的C函数原型必须把void写出来。而C++可以使用空参数列表。 C++中new和delete是对内存分配的运算符,取代了C中的malloc和free。 标准C++中的字符串类取代了C标准C函数库<cstring>头文件中的字符数组处理函数。 C++中用来做控制态输入输出的iostream类库替代了标准C中的stdio函数库。 C++中的try/catch/throw异常处理机制取代了标准C中的setjmp()和longjmp()函数。 面向对象有三大特征:封装性、继承性、多态性 1.面向对象和面向过程区别 面向过程程序设计:所谓的面向过程程序设计就是函数的定义和调用。简单地说,过程就是程序执行某项操作的一段代码

C++ Virtual 完美诠释

半腔热情 提交于 2020-03-22 18:03:43
解答了我的一些疑问,觉得写的不错!!!转载一下。 virtual在英文中表示“虚”、“虚拟”的含义。c++中的关键字“virtual”主要用在两个方面:虚函数与虚基类。下面将分别从这两个方面对virtual进行介绍。 1.虚函数 虚函数源于c++中的类继承,是多态的一种。在c++中,一个基类的指针或者引用可以指向或者引用派生类的对象。同时,派生类可以重写基类中的成员函数。这里“重写”的要求是函数的特征标(包括参数的数目、类型和顺序)以及返回值都必须与基类中的函数一致。如下所示: 可以在基类中将被重写的成员函数设置为虚函数,其含义是:当通过基类的指针或者引用调用该成员函数时,将根据指针指向的对象类型确定调用的函数,而非指针的类型。如下,是未将test()函数设置为虚函数前的执行结果: 在将test()函数设置为virtual后,执行结果如下: 如此,便可以将基类与派生类的同名方法区分开,实现多态。 说明: 1.只需将基类中的成员函数声明为虚函数即可,派生类中重写的virtual函数自动成为虚函数; 2.基类中的析构函数必须为虚函数,否则会出现对象释放错误。以上例说明,如果不将基类的析构函数声明为virtual,那么在调用delete p2;语句时将调用基类的析构函数,而不是应当调用的派生类的析构函数,从而出现对象释放错误的问题。 3.虚函数的使用将导致类对象占用更大的内存空间

剑指offer学习

女生的网名这么多〃 提交于 2020-03-22 08:26:41
问:C++定义一个空的类型,里面没有任何的成员变量和成员函数。对该类型求sizeof,得到的结果是多少? 答: 是1. 因为空类型的实例中不包含任何信息,本来求sizeof应该是0,但是当我们声明该类型的实例的时候,它必须在内存中占有一定的空间,否则无法使用这些实例。至于占用多少内存,由编译器决定。visual studio 中的每个空类型的实例占用1字节的空间。 如果在该类型中添加一个构造函数和析构函数,求得的sizeof的结果仍是1,因为,调用构造函数和析构函数只需要知道函数的地址即可。而这些函数的地址只与类型相关,而与类型的实例的无关,编译器也不会因为这两个函数而在实例内添加任何额外的信息。 如果把析构函数标记成虚函数的话,C++编译器会为该类型生成虚函数表,并在该类型的每一个实例中添加一个指向虚函数表的指针。 在32位机子上,一个指针占4字节的空间,因此求sizeof得到4; 如果是64位机子,一个指针占8字节的空间,因此求得sizeof得到8; 问: class A { private : int value; public: A (int n) { value =n; } A(A other) { value=other.value ;} void Print( ) {std::cout<<value<<std::endl;} }; int_tmain(int argc

C++ 虚函数列表与多态 —— 多态的简单用法

社会主义新天地 提交于 2020-03-22 03:56:01
首先看下边的代码,先创建一个父类,然后在来一个继承父类的子类,两个类中都有自己的 play() 方法,在代码的第35-37行,创建一个父类指针,然后将子类地址引用赋值给父类,这时调用 P 指针的 play() 方法会打印出什么呢。开始我以为会是调用子类的 play() 方法,因为第36行给引用了,但打印结果是:    这是个父类的play 1 #include <iostream> 2 3 class Father 4 { 5 public: 6 void play() 7 { 8 std::cout << "这是个父类的play" << std::endl; 9 } 10 }; 11 12 class Son : public Father 13 { 14 public: 15 void play() 16 { 17 std::cout << "这是个子类的Play" << std::endl; 18 } 19 }; 20 21 22 void party(Father** men, int num) 23 { 24 for (int i = 0; i < num; i++) 25 { 26 men[i]->play(); 27 } 28 } 29 30 int main() 31 { 32 Father father; 33 Son son; 34 35 Father* p;

C++的多态性

南楼画角 提交于 2020-03-21 06:53:17
1.静态多态 (1)函数重载 (2)操作符重载 2.动态多态 继承,虚函数 实现机制: 以下摘自于 http://blog.csdn.net/zyq0335/article/details/7657465 1 什么是多态? 多态性可以简单的概括为“1个接口,多种方法”,在程序运行的过程中才决定调用的机制 程序实现上是这样,通过父类指针调用子类的函数,可以让父类指针有多种形态。 2 实现机制 举一个例子: #include <iostream.h> class animal { public: void sleep() { cout<<"animal sleep"<<endl; } void breathe() { cout<<"animal breathe"<<endl; } }; class fish:public animal { public: void breathe() { cout<<"fish bubble"<<endl; } }; void main() { fish fh; animal *pAn=&fh; pAn->breathe(); } 答案是输出:animal breathe 结果分析: 1从编译的角度 C++编译器在编译的时候,要确定每个对象调用的函数的地址,这称为早期绑定(early binding),当我们将fish类的对象fh的地址赋给pAn时,C

近期团队博客的摘要 8

独自空忆成欢 提交于 2020-03-17 08:25:44
VS2008 SP1正式发布: WCF工具的相关功能和贴图 VS2008 SP1正式发布了! 在本篇文章中,我将会用贴图的形式向大家介绍在VS2008 SP1中由我们团队开发的WCF Tools 新功能。 点击这里 阅读全文。 在VS2008 SP1中WCF Tool的一些使用技巧 在这篇文章中,我将向大家分享一下在VS2008 SP1中WCF工具的一些使用技巧,希望能帮助大家更好的使用它们。 点击这里 阅读全文。 在VS2008 SP1中WCF Tools 相关的Readme文件 你可以在 这里 找到VS2008 SP1的readme文件。这里我摘抄了和WCF开发工具相关的两项。 点击这里 阅读全文。 SQL Server Build系统 你知道SQL Server这么庞大的企业级数据库服务器产品是如何build出来的吗? 点击这里 阅读全文。 使用IDispatch::Invoke函数在C++中调用C#实现的托管类库方法 CLR Interop简而言之是让非托管代码与托管代码之间可以相互调用的技术。这项技术可以使开发人员重用已有的托管或非托管组建,并根据自己的需要,权衡托管代码的简易性与非托管代码的灵活性,选择适合自己实际情况的编程语言,而不用过多考虑重用的组件是用哪种语言开发的。Interop中文的意思是互通性,既然是互通,代码的调用就有两种不同的方向

RTTI运行时类型识别

一曲冷凌霜 提交于 2020-03-17 05:40:36
RTTI是Runtime Type Identification的缩写,是“运行时类型识别”的意思。面向对象的编程语言,象C++, Java ,Delphi都提供了对RTTI的支持。 本文将简略介绍 RTTI 的一些背景知识、描述 RTTI 的概念,并通过具体例子和代码介绍什么时候使用以及如何使用 RTTI。本文还将详细描述两个重要的 RTTI 运算符的使用方法,它们是 typeid 和dynamic_cast。 1. typeid的用法 1.1type_info类 typeid 的结果是 const type_info&。所以下面先对type_info类作下介绍: class type_info { public: virtual ~type_info(); size_t hash_code() const _CRTIMP_PURE bool operator==(const type_info& rhs) const; _CRTIMP_PURE bool operator!=(const type_info& rhs) const; _CRTIMP_PURE int before(const type_info& rhs) const; _CRTIMP_PURE const char* name() const; _CRTIMP_PURE const char* raw

C++学习笔记--从虚函数说开去

。_饼干妹妹 提交于 2020-03-14 04:28:03
虚函数与纯虚函数 : 虚函数:在某基类中声明为virtual并在一个或多个派生类中被重新定义的成员函数,virtual 函数返回类型 函数名(参数表){函数体;} ,实现多态性, 通过指向派生类的基类指针或引用 ,访问派生类中同名覆盖成员函数。注意虚函数在基类中是有定义的,即便定义是空。 纯虚函数:在基类中是没有定义的,必须由派生类重定义实现,否则不能由对象进行调用。 看下面的例子: #include<iostream> using namespace std; class Cshape { public: void SetColor(int color){m_nColor=color;} virtual void Display(void){}; private: int m_nColor; }; class Crectangle:public Cshape{ //公有继承 public: }; void main() { Crectangle obRectangle; Cshape* pShape=&obRectangle; pShape->Display(); } 上面例子中,Display是虚函数,虽然是空定义,并且在派生类中没有重写该函数,但是上面的代码在编译阶段不会出错,而是在链接时出错,而如果将Display声明为纯虚函数,即 virtual void Display