虚函数感觉总是很神秘,在本质的原理上一直也没有弄得很透彻,今天又有一点的新的感悟,纪录下来,有时间的话可以去研究一下C++对象模型 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CSGrammar { class Program { static void Main(string[] args…
<c++编程思想>书上有一段话:在任何构造函数中,可能只是部分形成对象——我们只能知道基类已被初始化,但并不知道哪个类是从这个基类继承来的.然而,虚函数在继承层次上是“向前”和“向外”进行调用.它可以调用在派生类中的函数.如果我们在构造函数中也这样做,那么我们所调用的函数可能操作还没有被初始化的成员,这将导致灾难的发生. 这段话怎么理解?我是这样理解的:分两段理解.第一段话:在任何构造函数中,可能只是部分形成对象——我们只能知道基类已被初始化,但并不知道哪个类是从这个基类继承来的. 我这样理解…
1.构造函数不能为虚函数 当我们将构造函数定义为虚函数时,会直接报错: 首先回忆下以前学的virtual虚函数概念: 如果类定义了虚函数,创建对象时,则会分配内存空间,并且为该父类以及其所有子类的内存空间上额外分配一个虚函数表. 虚函数表的作用在于,存储每个类的相同的虚函数名,然后每一次虚函数调用,都会去虚函数表查找地址 分析: 假如构造函数是虚函数的话,由于对象开始还未分配内存空间,所以根本就无法找到虚函数表,从而构造函数也无法被调用.所以构造函数是不能成为虚函数. 2. 析构函数可以为虚函数…
1.控制台测试代码: #include <stdio.h> #include <windows.h> class A { public: A() { printf("A constructor\n"); } public: virtual void SayHi() { printf("A say hi\n"); } }; class B :public A { public: B() { printf("B constructor\…
一. 什么是拷贝构造函数 先看一个简单的例子: #include <iostream> using namespace std; class CExample { private: int a; public: //构造函数 CExample(int b) { a = b;} //一般函数 void Show () { cout<<a<<endl; } }; int main() { CExample A(); CExample B = A; //注意这里的对象初始化要…
//声明一个匿名函数并赋值给一个变量 var a = function(){ console.log("executing..."); } //匿名函数调用 a(); 相信上面这段代码大家都能看明白,再看下面这段代码 console.log(a() === (a)()); //结果true 于是,下面这段代码也就不难理解了 (function(){ console.log("executing..."); })(); 但是 //结果"缺少标识符"…
一般来说c传值分为传值与传指针,Java里没有指针,因此只有传值,但是Java里传值分为简单变量传值和引用型变量传值,从本质上来说这两者没啥区别. 下面主要说的是传参时对原变量的影响: 最初练习创建单链表时可能会有这样一种写法: void Creat_link_list(int n,struct node *head){ } n是单链表节点的个数,head被初始化为null,调用该函数后可能会有人直接对head进行各种操作,比如遍历,排序.但此时head依然为null,函数内的一列操作只是hea…
从存储空间角度,虚函数对应一个指向vtable虚函数表的指针,这大家都知道,可是这个指向vtable的指针其实是存储在对象的内存空间的.问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数. 从使用角度,虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用.构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀.所以构造函数没有必要是虚函数.虚函数的作用在于通过父类的指针或者引用来…
6.3.3  用虚函数实现多态 在理解了面向对象的继承机制之后,我们知道了在大多数情况下派生类是基类的“一种”,就像“学生”是“人”类中的一种一样.既然“学生”是“人”的一种,那么在使用“人”这个概念的时候,这个“人”可以指的是“学生”,而“学生”也可以应用在“人”的场合.比如可以问“教室里有多少人”,实际上问的是“教室里有多少学生”.这种用基类指代派生类的关系反映到C++中,就是基类指针可以指向派生类的对象,而派生类的对象也可以当成基类对象使用.这样的解释对大家来说是不是很抽象呢?没关系,可以…
接口只能声明不能实现,虚函数可以. 接口:对外提供可以访问的函数叫接口.虚函数不需要被强制重写,其本身含有实现部分. 抽象类:指派了派生类必须实现的函数(纯虚函数),不然编译不通过. 虚函数的限制:    1.虚函数仅适用于有继承关系的类对象,   所以只有类的成员函数才能说明为虚函数.      2.静态成员函数不能是虚函数.      3.内联函数不能是虚函数.      4构造函数不能是虚函数.      5.析构函数可以是虚函数. 接口可以有静态成员.嵌套类型.抽象.虚拟成员.属性和事件…