打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
c++ virtual 虚函数 =0 等于零的作用 | KingPlesk Web Hosting Control Panel Free KingCP
userphoto

2015.04.09

关注

我们根据一个例子来学习 virtual 函数=0 的知识

重要补充: 类中包含纯虚函数,这个类就不能实例化(初始化) 例如 Animal类有纯虚函数
Animal a; 这样是错误的
error: cannot declare variable ‘animal’ to be of abstract type ‘Animal’

如果学过c# java 都会知道 它们有 abstract 的概念, c++也是面向对象语言,也不例外也有这样的概念,表现形式却跟java 不一样

抽象类中不一定要包含abstract方法,但一个类中包含了abstract方法,则这个类必须声明为abstract类。
抽象类的实现子类必须实现抽象类中所有的abstract方法

抽象类中的函数分为 虚函数,普通函数,纯虚函数, 虚函数和普通成员函数 都必须要在基类中实现,如果不实现会造成编译错误.

编译器发现一个类中有被声明为virtual的函数,就会为其搞一个虚函数表,也就是VTABLE。VTABLE实际上是一个函数指针的数组,每个虚函数占用这个数组的一个slot。一个类只有一个VTABLE,不管它有多少个实例。派生类有自己的VTABLE,但是派生类的VTABLE与基类的VTABLE有相同的函数排列顺序,同名的虚函数被放在两个数组的相同位置上。在创建类实例的时候,编译器还会在每个实例的内存布局中增加一个vptr字段,该字段指向本类的VTABLE。
如果是虚函数 未实现,会出现如下错如

src\Animal.o:Animal.cpp:(.rdata$_ZTV6Animal[vtable for Animal]+0×10): undefined reference to `Animal::hello()’

其中提到 vtable for Animal
就是说,如果 new 子类的时候 , 父类没有实现virtual 函数, 就会说undefined reference  ,
当使用
基类* p = new 子类
p->会调用基类的虚函数,就会出现上述错误,不过这个错误是在 编译时检查出来的。

看例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * Animal.h
 *
 *  Created on: 2011-6-10
 *      Author: Administrator
 */

#ifndef ANIMAL_H_
#define ANIMAL_H_

class Animal {
public:
    Animal();
    virtual ~Animal();
    virtual void hello() = 0;
};

#endif /* ANIMAL_H_ */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * Animal.cpp
 *
 *  Created on: 2011-6-10
 *      Author: Administrator
 */

#include "Animal.h"
Animal::Animal() {
    // TODO Auto-generated constructor stub

}

Animal::~Animal() {
    // TODO Auto-generated destructor stub
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * Dog.h
 *
 *  Created on: 2011-6-10
 *      Author: Administrator
 */

#ifndef DOG_H_
#define DOG_H_

#include "Animal.h"

class Dog: public Animal {
public:
    Dog();
    virtual ~Dog();
    virtual void hello();
};

#endif /* DOG_H_ */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * Dog.cpp
 *
 *  Created on: 2011-6-10
 *      Author: Administrator
 */
#include <iostream>
#include "Dog.h"

Dog::Dog() {
    // TODO Auto-generated constructor stub

}

Dog::~Dog() {
    // TODO Auto-generated destructor stub
}

void Dog::hello(){
    std::cout <<"Dog::hello()"<<std::endl;
}

测试 main函数

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include "Animal.h"
#include "Dog.h"
using namespace std;

int main() {
    Dog *g = new Dog();
    Animal *a = g;
    g->hello();
    a->hello();//Animal class调用的也是Dog的virtual函数
    delete g;
    return 0;
}

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
抽象类能实例化吗
C++中的虚函数(virtual function)
C#中virtual和abstract的区别
java学习总结-高级语言特性-封装,继承,多态
《Java面向对象程序设计》09 抽象类与接口写字字帖
好程序员Java分享实用教程系列之对象的转型
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服