1、c语言中的多态,动态绑定和静态绑定

void do_speak(void(*speak)())
{
speak();
} void pig_speak()
{
cout << "猪叫..." << endl;
} void cat_speak()
{
cout << "猫叫..." << endl;
} void test01()
{
do_speak(cat_speak);
}

C++中的多态:

class Animal
{
public:
// 虚函数
virtual void speak()
{
cout << "动物在叫唤..." << endl;
} void func()
{ }
}; class Cat : public Animal
{
public:
Cat(string name)
{
m_name = name;
} void speak()
{
cout << m_name << " 在叫唤..." << endl;
} void func()
{ }
public:
string m_name;
}; class Dog : public Animal
{
public:
Dog(string name)
{
m_name = name;
} void speak()
{
cout << m_name << " 在汪汪..." << endl;
} void func()
{ }
public:
string m_name;
}; class Pig : public Animal
{
public:
void speak()
{
cout << " 猪在叫..." << endl;
}
};

1、静态绑定

  (1) 编译器会根据指针类型、引用类型来确定函数调用。

  (2) 如果要实现根据传递不同对象,调用不同对象的speak,就要进行动态绑定。

2、动态绑定

  (1) 根据引用或者指针,实际指向的类型来确定函数调用。

  (2) 虚函数机制可以让编译器实现动态绑定。

3、实现多态的条件

  (1) 表现形式:父类指针或者引用指向子类对象。

  (2) 父类必须要有虚函数。

  (3) 子类必须重写父类的虚函数,如果不重写,默认调用的父类函数。

  (4) 父类纸质恩、或者引用指向子类对象。

虚函数的机制:

1、如果类的内部包含了虚函数,编译器首先会在类中安插虚函数表指针vfptr,vfptr指向一张表,这张表中存储的类中所有的虚函数入口地址。

2、当子类继承了父类,会将父类的虚函数表指针继承下来。一开始该虚函数指针指向父类的虚函数表,在子类中的构造函数中,编译器将其重新指向到了子类自己的虚函数表。

3、当子类重写了父类的虚函数,在虚函数表中会用子类的虚函数地址去覆盖父类对应虚函数的函数地址。

4、当通过父类指针、引用调用函数时,编译器会先找到该对象中隐藏存储的vfptr指针,根据虚函数指针找到虚函数表,在虚函数表中找到对应的函数入口地址,进行执行。

虚函数代码实现:

class Animal
{
public:
// 虚函数
virtual void speak()
{
cout << "动物在叫唤..." << endl;
} void func()
{ }
}; class Cat : public Animal
{
public:
Cat(string name)
{
m_name = name;
} void speak()
{
cout << m_name << " 在叫唤..." << endl;
} void func()
{ }
public:
string m_name;
}; class Dog : public Animal
{
public:
Dog(string name)
{
m_name = name;
} void speak()
{
cout << m_name << " 在汪汪..." << endl;
} void func()
{ }
public:
string m_name;
}; class Pig : public Animal
{
public:
void speak()
{
cout << " 猪在叫..." << endl;
}
};

C++中对C的扩展学习新增内容———面向对象(继承)函数扩展性及虚函数机制的更多相关文章

  1. C++中对C的扩展学习新增内容———面向对象(封装)

    面向对象(封装) 1.对封装的理解: 1.封装就是把变量和函数放在一起统一表示某一个食物. class 2.给类内部的成员增加访问控制权限. 3.封装的语法就是class定义一个类. 2.给对象成员增 ...

  2. C++中对C的扩展学习新增语法——内联函数以及函数参数

    内联函数以及函数参数 内联函数 使用 inline 关键字必须和函数体放在一起. 内联函数具有内部链接属性. 内联函数会被编译器在编译阶段替换到函数调用的地方. 可以把内联函数定义写到头文件中,多个c ...

  3. C++中对C的扩展学习新增语法——动态内存管理

    1.C语言动态内存管理的缺点: 1.malloc对象的大小需要自己计算. 2.需要手动转换指针类型. 3.C++的对象不适合使用malloc和free. 2.C++中new/delete基本使用: 3 ...

  4. C++中对C的扩展学习新增语法——强枚举

    枚举类型 C++中对枚举的加强: 1.C++不允许非枚举值赋值给枚举类型,不允许其他枚举类型的值赋值给当前枚举类型,而C语言中是允许的. 2.枚举值具有外层作用域,容易造成名字冲突. 3.不同类型的枚 ...

  5. C++中对C的扩展学习新增语法——引用

    引用 引用的好处: 1.引用的好处 C++使用结构体,不需要再使用 typedef. 2.值传递是将实参进行拷贝,赋值给形参,如果对象比较大,每次拷贝效率比较低,并且函数内部无法修改外部变量的值,能力 ...

  6. C++中对C的扩展学习新增语法——const

     Const Const在C语言和C++语言中连接属性不一样,C语言默认是外部连接,如果需要内部连接,需要显示写上static.而在C++中默认是内部连接,如果希望其编程外部变量,需要显示写上exte ...

  7. C++中对C的扩展学习新增语法——强制类型转换

    类型转换:主要进行指针类型转换,因为在C++中,不同类型指针不允许隐式转换,任何一个程序中如果出现了大量的类型转换,说明该程序不是太好的程序. 注意事项: 不同类型指针不允许隐式转换: void* 类 ...

  8. C++中对C的扩展学习新增语法——namespace

    NAMESPACE语法 namespace主要解决了命名冲突的问题,语法如下 Namespace注意事项: namespace中可以定义常量.变量.函数.结构体.枚举.类等. namespace 只能 ...

  9. C++中对C的扩展学习新增语法——函数重载

    函数重载 1.函数重载语法 1.同一个作用域(全局作用域.命名空间作用域.类作用域) 2.参数个数不同 3.参数类型不同 4.参数顺序不同 代码实现: 当函数名字一样的时候,通过参数类型.参数个数.参 ...

随机推荐

  1. Cobalt Strike之CHM、LNK、HTA钓鱼

    CHM钓鱼 CHM介绍 CHM(Compiled Help Manual)即“已编译的帮助文件”.它是微软新一代的帮助文件格式,利用HTML作源文,把帮助内容以类似数据库的形式编译储存.利用CHM钓鱼 ...

  2. Linux提权中常见命令大全

    在拿到一个 webshell 之后,大家首先会想到去把自己的权限提升到最高,windows 我们会提升到 SYSTEM 权限,而 Linux 我们会提升到 root 权限,拿在进行 Linux 提权的 ...

  3. wireshark分析https

    0x01 分析淘宝网站的https数据流 打开淘宝 wireshark抓取到如下 第一部分: 因为https是基于http协议上的,可以看到首先也是和http协议一样的常规的TCP三次握手的连接建立, ...

  4. freertos学习

    freertos的基本框架如下 注意有三点很重要: 1.任务的资源 (1)任务优先级:freertos 能够调度的任务优先级在freertosConfig.h中的configMAX_PRIORITIE ...

  5. boost::asio::tcp

    同步TCP通信服务端 #include <boost/asio.hpp> #include <iostream> using namespace boost::asio; in ...

  6. JS中==运行机制

    1. 判断两边是否有NaN,如果有则一律返回false 2.判断两边是否含有布尔值,如果有的话则将true转化为1,false转化为0. 3.遇到null或者undefined,则不会进行类型转换,它 ...

  7. 如何利用Fiddler4进行Android APP / IOS APP抓包

    Fiddler抓包 1.Fiddler介绍 Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有的“进出”Fiddler的数据. F ...

  8. [最新方法]终于解决了 Ubuntu 14.04 网络图标不见了 的问题|Ubuntu14.04 网络图标消失

    解决 Ubuntu 14.04 网络图标不见了 消失的问题   这个问题困扰了我大半年了.但是我就硬是不想重新装系统.搜索研究一番发现,这个问题是nm-applet的问题.   然后偶然发现nm-ap ...

  9. React Ref 和 React forwardRef

    Ref 和Dom,Ref是reference(引用)的简写. 能力:大多数情况下,props前递可以解决一切问题,但是依然有需要触达React实例或者Dom节点的情况,这时候应该使用React Ref ...

  10. C#操作sql server

    C#操作sqlserver跟操作其他数据没有太大差别,但是又一些细节要注意一下. 在安装sqlserver时不要选择默认实例,如果是则需要更改设置,还有远程连接要去连接服务中设置一下,如端口1433等 ...