C++ 虚函数、纯虚函数、虚继承
1)C++利用虚函数来实现多态。
程序执行时的多态性通过虚函数体现,实现运行时多态性的机制称爲动态绑定;与编译时的多态性(通过函数重载、运算符重载体现,称爲静态绑定)相对应。
在成员函数的声明前加上virtual修饰,派生类可以不加virtual修饰,则声明之为虚函数。在派生类中可以重新定义从基类继承下来的虚函数。下面是一个例子,Rectangle是Shape的派生类,在类Rectangle中对Shape中的虚函数Draw()进行了重新定义:
class Shape {
public:
virtual void Draw() { }
};
class Rectangle : public Shape {
public:
virtual void Draw() { }
};
类Rectangle中的Draw()函数前面的virtual可不加,那麽它就不再可以被它的继承类重新定义。
虚函数的调用
要想调用一个在派生类中重定义的函数,必须使用多态调用,它必须使用指针来实现。下面是一个典型的例子:
void fun1(Shape s) { s.Draw(); } //非多态
void fun2(Shape &s) { s.Draw(); } //多态
void fun3(Shape *s) { s->Draw(); } //多态
int main()
{
Rectangle rr;
fun1(rr); //调用类Shape的Draw()
fun2(rr); //调用类Rectangle的Draw()
fun3(&rr); //调用类Rectangle的Draw()
}
只有使用指针和引用调用时,才能进行多态调用。
2)技巧:虚函数的调用地址只看对象声明时的类名(看后面),普通函数的调用地址看对象定义时的类名(看前面)。
所以构造函数不能是虚函数,而析构函数最好是虚函数。
如下:
#include<iostream>
using namespace std; class A
{
public:
void foo()
{
printf("1\n");
}
virtual void fun()
{
printf("2\n");
}
};
class B : public A
{
public:
void foo()
{
printf("3\n");
}
void fun()
{
printf("4\n");
}
};
int main(void)
{
A a;
B b;
A *p = &a;
p->foo(); //1
p->fun(); //2
p = &b;
p->foo(); //1,普通函数看前面,调用的就是A类的方法。
p->fun(); //4,虚函数看后面,调用的是 B类的方法。
return ;
}
B *ptr = (B *)&a;
ptr->foo(); //3,普通函数看前面,所以调用的是 B类的方法。
ptr->fun(); //2,虚函数看后面,所以调用的是A类的方法。
原理可以看这篇文章:
C++虚函数与虚函数表
3)纯虚函数
纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”
virtual void funtion()=
类似于java里的interface,派生类必须要实现它。
4)虚继承
参考:c++ 虚继承详解 http://blog.163.com/redhumor@126/blog/static/19554784201131174216260/
C++ 虚函数、纯虚函数、虚继承的更多相关文章
- C++ 子类继承父类纯虚函数、虚函数和普通函数的区别
C++三大特性:封装.继承.多态,今天给大家好好说说继承的奥妙 1.虚函数: C++的虚函数主要作用是“运行时多态”,父类中提供虚函数的实现,为子类提供默认的函数实现.子类可以重写父类的虚函数实现子类 ...
- C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别
1.虚函数(impure virtual) C++的虚函数主要作用是“运行时多态”,父类中提供虚函数的实现,为子类提供默认的函数实现. 子类可以重写父类的虚函数实现子类的特殊化. 如下就是一个父类中的 ...
- 虚函数&纯虚函数&抽象类&虚继承
C++ 虚函数&纯虚函数&抽象类&接口&虚基类 1. 多态 在面向对象语言中,接口的多种不同实现方式即为多态.多态是指,用父类的指针指向子类的实例(对象),然后通过 ...
- 从零开始学C++之虚函数与多态(二):纯虚函数、抽象类、虚析构函数
一.纯虚函数 虚函数是实现多态性的前提 需要在基类中定义共同的接口 接口要定义为虚函数 如果基类的接口没办法实现怎么办? 如形状类Shape 解决方法 将这些接口定义为纯虚函数 在基类中不能给出有意义 ...
- C++多态、虚函数、纯虚函数、抽象类、虚基类
一.C++多态 C++的多态包括静态多态和动态多态.静态多态包括函数重载和泛型编程,动态多态包括虚函数.静态多态是指在编译期间就可以确定,动态多态是指在程序运行时才能确定. 二.虚函数 1.虚函数为类 ...
- C++纯虚函数、虚函数、实函数、抽象类,重载、重写、重定义
首先,面向对象程序设计(object-oriented programming)的核心思想是数据抽象.继承.动态绑定.通过数据抽象,可以使类的接口与实现分离,使用继承,可以更容易地定义与其他类相似但不 ...
- 【转】C++ 虚函数&纯虚函数&抽象类&接口&虚基类
1. 动态多态 在面向对象语言中,接口的多种不同实现方式即为多态.多态是指,用父类的指针指向子类的实例(对象),然后通过父类的指针调用实际子类的成员函数. 多态性就是允许将子类类型的指针赋值给父类类型 ...
- C++ 虚函数&纯虚函数&抽象类&接口&虚基类(转)
http://www.cnblogs.com/fly1988happy/archive/2012/09/25/2701237.html 1. 多态 在面向对象语言中,接口的多种不同实现方式即为多态.多 ...
- c++ 虚函数多态、纯虚函数、虚函数表指针、虚基类表指针详解
静态多态.动态多态 静态多态:程序在编译阶段就可以确定调用哪个函数.这种情况叫做静态多态.比如重载,编译器根据传递给函数的参数和函数名决定具体要使用哪一个函数.动态多态:在运行期间才可以确定最终调用的 ...
- 虚函数的使用 以及虚函数与重载的关系, 空虚函数的作用,纯虚函数->抽象类,基类虚析构函数使释放对象更彻底
为了访问公有派生类的特定成员,可以通过讲基类指针显示转换为派生类指针. 也可以将基类的非静态成员函数定义为虚函数(在函数前加上virtual) #include<iostream> usi ...
随机推荐
- dubbo心跳机制 (3)
此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 二.consumer端心跳机制 //创建ExchangeClie ...
- 基于注解的AOP配置
配置文件 spring配置文件中的约束 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns ...
- pandas-如何得到某一个值所在的行
df[df['列名'].isin([相应的值])]
- 在SQLSERVER中创建聚集索引
CREATE CLUSTERED INDEX CLUSTER_id ON TABLE_name(ID)------批量
- java程序设计实验
建立文件调试jdk idea断点调试 项目素数的寻遍
- HTTP协议和WebSocket协议(一)
转自:https://www.jianshu.com/p/0e5b946880b4# HTTP HTTP的地址格式如下: http_URL = "http:" "//&q ...
- [Groovy]Groovy with Ant Task
平时经常会用Ant来写一写脚本,但最近跨入到Groovy的时代,试着做一些改变.Groovy里集成了AntBuilder能非常方便的调用到Ant的对象模型. 现考察如下 1. Groovy里定义的属性 ...
- C语言中typedef的解释_1
typedef是在计算机编程语言中用来为复杂的声明定义简单的别名,它与宏定义有些差异. 它本身是一种存储类的关键字,与auto.extern.mutable.static.register等关键字不能 ...
- 75th LeetCode Weekly Contest Champagne Tower
We stack glasses in a pyramid, where the first row has 1 glass, the second row has 2 glasses, and so ...
- 经典SQL行列转换
-- http://www.programbbs.com/doc/4885.htm /* 标题:普通行列转换(version 2.0) 说明:普通行列转换(version 1.0)仅针对sql ser ...