多态&虚函数
class A
{};
class B:public A
{};
int main()
{
B* b;
A* a=b;//a的静态类型是A*,动态类型(运行时)类型是B*
return ;
}
int Add(int a,int b)
{
return a+b;
}
float Add(float a,float b)
{
return a+b;
}
int main()
{
cout<<Add(,)<<endl;;
cout<<Add(10.1f,20.2f)<<endl;;
return ;
}
在编译期间,编译器会根据函数实参的类型推断要调用那个函数
class A
{
public:
virtual void fun()
{
cout<<"A-fun()"<<endl;
}
A()
{}
~A()
{}
private:
int a1;
};
class B:public A
{
public:
void fun()
{
cout<<"B-fun()"<<endl;
}
B()
{}
~B()
{}
private:
int b1;
};
2)子类定义了新的虚函数:
class A
{
public:
virtual void fun()
{
cout<<"A-fun()"<<endl;
}
A()
{}
~A()
{}
private:
int a1;
};
class B:public A
{
public:
virtual void fun1()
{
cout<<"B-fun()"<<endl;
}
B()
{}
~B()
{}
private:
int b1;
};![]()
class A
{
public:
virtual void Afun()
{}
private:
int a1;
};
class B
{
public:
virtual void Bfun()
{}
private:
int b1;
};
class C:public A,public B
{
public:
void Afun()
{}
void Bfun()
{}
private:
int c1;
};
int main()
{
A a;
B b;
C c;
cout<<sizeof(a)<<endl;
cout<<(int*)(&a)<<endl;
cout<<sizeof(b)<<endl;
cout<<(int*)(&b)<<endl;
cout<<sizeof(c)<<endl;
cout<<(int*)(&c)<<endl;
return ;
}
2)子类定义新的虚函数
class A
{
public:
virtual void Afun()
{}
private:
int a1;
};
class B
{
public:
virtual void Bfun()
{}
private:
int b1;
};
class C:public A,public B
{
public:
virtual void Cfun()
{}
private:
int c1;
};
int main()
{
A a;
B b;
C c;
cout<<sizeof(a)<<endl;
cout<<(int*)(&a)<<endl;
cout<<sizeof(b)<<endl;
cout<<(int*)(&b)<<endl;
cout<<sizeof(c)<<endl;
cout<<(int*)(&c)<<endl;
return ;
}
3) 菱形继承
class A
{
public:
void Afun()
{
cout<<"Afun()"<<endl;
}
A()
{}
~A()
{}
private:
int a1;
};
class B:public A
{
public:
void Bfun()
{
cout<<"Bfun()"<<endl;
}
B()
{}
~B()
{}
private:
int b1;
};
class C:public A
{
public:
void Cfun()
{
cout<<"Cfun()"<<endl;
}
private:
int c1;
};
class D:public B,public C
{
public:
void Dfun()
{
cout<<"D-fun()"<<endl;
}
private:
int d1;
};
class A
{
public:
virtual void Afun()
{}
private:
int a1;
};
class B:virtual public A
{
public:
void Afun()
{}
private:
int b1;
};
给B实例化一个对象,它的大小是16,是因为在虚继承过程中,会出现对应的虚类指针
***虚函数的主要作用是为了实现多态机制
class Base
{
virtual void print(void);
};
class Drive1:public Base
{
virtual void print(void);
};
class Drive2:public Base
{
virtual void print(void);
};
int main(int argc,char* argv[])
{
Base* ptr1=new Base;
Base* ptr2=new Drive1;
Base* ptr3=new Drive2;
ptr1->print();//调用base::print()
ptr2->print();//调用Drive1::print()
ptr3->print();//调用Drive2::print()
return ;
}这是一种运行期多态,父类指针唯有在程序运行时才能知道所致的真正类型是什么,这种运行期决议是通过虚函数表来实现的
***使用指针访问虚表
class Base
{
public:
Base(int i)
:base1(i)
{}
virtual void print(void)
{
cout<<"Base::print()"<<endl;
}
virtual void setl(void)
{
cout<<"Base::setl"<<endl;
}
virtual ~Base()
{}
private:
int base1;
};
int main(int argc,char* argv[])
{
Base b();
int* vptrAdree=(int*)(&b);
cout<<"虚函数指针(vptr)的地址是:\t"<<vptrAdree<<endl;
return ;
}
当一个类本身定义了虚函数或者其父类有虚函数时,为了支持多态机制,编译器为该类添加了一个虚函数指针(vptr),虚函数指针一般放在对象内存布局的第一个位置上,这是为了保证在多层继承或多重继承的情况下能以最高效率取到虚表
这个代码的mian()里我们取到了虚函数的地址(vptrAdree),虚函数指针指向虚函数表,虚函数表存的是一系列虚函数的地址,虚函数地址出现的顺序与类中虚函数声明的顺序一致
多态&虚函数的更多相关文章
- C++ (P199—P211)多态 虚函数 抽象类
在介绍多态之前,先回忆:赋值兼容原则.虚基类.二义性.派生类如何给基类赋值等知识. 在赋值兼容原则中:父类对象的指针赋给基类的指针或者父类的对象赋给基类的引用,可以通过强转基类的指针或者引用变为父类的 ...
- 看懂下面C++代码才说你理解了C++多态虚函数!
#include <iostream> using namespace std ; class Father { private : virtual void Say() //只有添加 ...
- OOP 多态/虚函数
// main.cpp // OOP // 虚函数允许继承层次结构中绝大多数特定版本的成员函数被选择执行,虚函数使多态成为可能. // Created by mac on 2019/4/8. // C ...
- C++继承-重载-多态-虚函数
C++ 继承 基类 & 派生类 一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数.定义一个派生类,我们使用一个类派生列表来指定基类.类派生列表以一个或多个基类命名,形式如下: ...
- c++学习之多态(虚函数和纯虚函数)
c++是面向对象语言,面向对象有个重要特点,就是继承和多态.继承之前学过了,就是一种重用类的设计方式.原有的类叫父类,或者基类,继承父类的类叫子类.在设计模式中,我们总是要避免继承,推荐用组合.因为继 ...
- C++: 多态 虚函数
一.多态: 1.多态是什么:具有不同功能的函数可以用同一个函数名 2.静态多态:程序编译时决定,通过函数重载实现. 3.动态多态:程序运行时决定,通过虚函数实现. 二.虚函数: 1.引入目的:可以通过 ...
- C++基础 (6) 第六天 继承 虚函数 虚继承 多态 虚函数
继承是一种耦合度很强的关系 和父类代码很多都重复的 2 继承的概念 3 继承的概念和推演 语法: class 派生类:访问修饰符 基类 代码: … … 4 继承方式与访问控制权限 相对的说法: 爹派生 ...
- 【C++基础】 多态 虚函数
多态:同样的消息被不同类型的对象接收时导致不同的行为.这里“消息”是对类的成员函数的调用,“行为”调用了不同的函数. 分类:①重载多态 ②包含多态……等 实现:编译时的多态 运行时的多态(动态绑定) ...
- C++ polymorphism Virtual Function 多态 虚函数
Polymorphism in C++ https://www.tutorialspoint.com/cplusplus/cpp_polymorphism.htm https://github.com ...
随机推荐
- 堆排序(Heapsort)
class Program { static void Main(string[] args) { , , , , , ,}; int size = arr.Length; Heapsort(arr, ...
- python字符串前面的r/u/b的意义 (笔记)
u/U:表示unicode字符串 : 不是仅仅是针对中文, 可以针对任何的字符串,代表是对字符串进行unicode编码. r/R:非转义的原始字符串: 与普通字符相比,其他相对特殊的字符,其中可能包含 ...
- 代码: 两列图片瀑布流(一次后台取数据,图片懒加载。下拉后分批显示图片。图片高度未知,当图片onload后才显示容器)
代码: 两列图片瀑布流(一次后台取数据,无ajax,图片懒加载.下拉后分批显示图片.图片高度未知,当图片onload后才显示容器) [思路]: 图片瀑布流,网上代码有多种实现方式,也有各类插件.没找到 ...
- leetcode337
/** * Definition for a binary tree node. * public class TreeNode { * public int val; * public TreeNo ...
- db2 SQL6036N解决办法
问题背景: 数据库在进行大量的运算和数据处理的过程中,IO.CPU等资源消耗非常高的时候,强制停止数据库.db2stop force 结果数据库命令迟迟没有响应.这个时候对数据库进行其他操作均无响应, ...
- Java虚拟机 垃圾收集器与内存分配策略
说起GC,我们要思考的主要有三件事 哪些内存需要回收 那些已经“死去”的对象,那么哪些对象“死”,哪些对象“活”呢,有个简单的办法 引用计数法,但是没法解决循环依赖问题 所以Java虚拟机采用的是可达 ...
- nlp算法工程师养成记 目标要求
时间规定: 2018.12.07-2018.02.15 能力养成: linux, shell python, c++(会多少算多少) tensorflow, keras, pytorch(tf优先) ...
- 20175314 《Java程序设计》第三周学习总结
20175314 <Java程序设计>第三周学习总结 教材学习内容总结 编程语言的发展事是从面向机器(汇编.机器)到面向过程(C)再到面向对象(Java) 成员变量: 1.成员变量定义在类 ...
- jsp相关笔记(二)
在jsp中将数据库表格内容读出为一个表格,并在表格中添加超链接: <%@ page language="java" contentType="text/html; ...
- python 2与python3 区别
源码区别 python3:python2 a) py3 优美简单清晰. b) py2:源码重复,混乱,不规范,冗(rong)余(不需要特多,啰嗦). test a) py3:可以中文也可以英文( ...



