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. opencv::图像上采样和降采样

    图像金字塔概念 . 我们在图像处理中常常会调整图像大小,最常见的就是放大(zoom in)和缩小(zoom out),尽管几何变换也可以实现图像放大和缩小,但是这里我们介绍图像金字塔 . 一个图像金字 ...

  2. win10下安装openssl

    1.下载运行工具:ActivePerl-5.22.1.2201-MSWin32-x64-299574.msi, 安装. 2.执行:perl example.pl,若显示“Hello from Acti ...

  3. CentOS6.5下搭建FTP服务

    一.FTP协议 FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一.FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端.其中FT ...

  4. Vulnhub靶场渗透练习(五) Lazysysadmin

    第一步扫描ip    nmap 192.168.18.*  获取ip 192.168.18.147 扫描端口 root@kali:~# masscan - --rate= Starting massc ...

  5. postman-windows下newman的使用

    一.newman的安装 1.安装node.js下载https://nodejs.org/en/ C:\Users\iphauser>node -vv10.16.1C:\Users\iphause ...

  6. python学习-列表、元组和字典(三)

    学习笔记中的源码:传送门 3.1 列表和元组 3.2 不同类型变量的初始化: 数值 digital_value = 0 字符串 str_value = "" 或 str_value ...

  7. django-表单之模型表单渲染(六)

    class StudentForms(forms.ModelForm): formats=[ '%Y-%m-%d', '%m/%d/%Y', ] birthday = forms.DateField( ...

  8. python wraps的作用

    1.__name__用来显示函数的名称,__doc__用来显示文档字符串也就是("""文档字符串""")这里面的内容 2.首先我们来看不加@ ...

  9. RSA学习1

    对PEM文件(以前是一个邮件编码)进行编码,得到RSA公钥.国密的RSA标准,一般是tlv(tag-version)格式的. 明文hash后的数据进行BER编码再进行加密.-签名 对于RSA的结构,全 ...

  10. Blazor之ABC

    .net core正式推出了Blazor, 正好在一个小项目里试用一下. 建立项目 因为基于WebAssemble的客户端Blazor还不是正式版, 为了避免不必要的麻烦,我试用服务端的Blazor. ...