c++ 基础5、关于虚函数的那些事

本文详细介绍了C++中的虚函数,包括普通虚函数的定义,虚函数的覆盖,纯虚函数的使用,以及在多态中析构函数的处理。同时,解释了静态函数为何不能为虚函数以及构造函数不能为虚函数的原因。通过对这些概念的探讨,深入理解C++中虚函数的关键作用和用法。
摘要由CSDN通过智能技术生成

c++ 中虚函数使用的非常广泛,关于虚函数有挺多用法的,各有各的不同

1、普通虚函数的定义

 普通虚函数就是在函数前面加virtual 关键词 ,有虚函数的类中会存在一个虚函数指针在类内存布局中的开头,虚函数指针为4字节,指向虚函数表,虚函数表里面存储的是虚函数的函数指针地址

#include <iostream>
#include <stdlib.h>
#include <stdio.h>

/// 虚函数类
class virtual_class {

public:
	~virtual_class() = default;
	virtual_class() = default;
	virtual void fun() {
		std::cout << "hello virtual fun" << std::endl;
	};
};

int main()
{
	virtual_class demo;
	demo.fun();
}

2、虚函数的覆盖

在继承关系中虚函数的覆盖,子类覆盖父类的函数,覆盖函数名字相同、返回值相同、传参相同,如果父类存在虚函数,则继承情况下子类也会继承父类的虚函数表,存在覆盖情况,子类的函数会

替换掉虚函数表里面的函数指针指向

#include <iostream>
#include <stdlib.h>
#include <stdio.h>


/// 虚函数类
class virtual_class {

public:
	~virtual_class() = default;
	virtual_class() = default;
	virtual void fun() {
		std::cout << "hello virtual_class fun" << std::endl;
	};
};

///虚函数的覆盖
class virtual_class2 :public virtual_class {

public:
	virtual_class2() = default;
	~virtual_class2() = default;
	void fun() {
		std::cout << "hello virtual_class2 fun" << std::endl;
	}
};

int main()
{
	virtual_class demo;
	demo.fun();
	virtual_class2 demo2;
	demo2.fun();
}

3、纯虚函数的使用

纯虚函数的定义,在虚函数后面使用 =0

#include <iostream>
#include <stdlib.h>
#include <stdio.h>

/// 虚函数类
class virtual_class {

public:
	virtual ~virtual_class() {
		std::cout << " virtual_class 析构" << std::endl;
	}
	virtual_class() { }
	virtual void fun() {
		std::cout << "hello virtual_class fun" << std::endl;
	};
    /// 纯虚函数
	virtual void setvalue(int va) = 0;
};

class virtual_class2 :public virtual_class {

public:
	virtual_class2() {}
	~virtual_class2() {
		std::cout << " virtual_class2 析构" << std::endl;
	}
	void fun() {
		std::cout << "hello virtual_class2 fun" << std::endl;
	}
	void setvalue(int va) {
		value = va;
	}
private:
	int value;
};

4、多态中虚函数的析构

在多态继承的情况下,基类的析构函数要设置成虚函数,设置成虚函数的目的是在子类转成父类情况下,子类可以进行正常的析构,如果不设置成虚函数,子类最后会没有得到释放。析构函数的顺序从父类析构 ----》子类析构。

#include <iostream>
#include <stdlib.h>
#include <stdio.h>

/// 虚函数类
class virtual_class {

public:
	virtual ~virtual_class() {
		std::cout << " virtual_class 析构" << std::endl;
	}
	virtual_class() { }
	virtual void fun() {
		std::cout << "hello virtual_class fun" << std::endl;
	};
};

class virtual_class2 :public virtual_class {

public:
	virtual_class2() {}
	~virtual_class2() {
		std::cout << " virtual_class2 析构" << std::endl;
	}
	void fun() {
		std::cout << "hello virtual_class2 fun" << std::endl;
	}
};

virtual_class* getVirtual()
{
	return new virtual_class2;
}

int main()
{
	virtual_class* demo4 = getVirtual();
	delete demo4;
}

4、静态函数可以设置成虚函数吗?

原因如下: 静态函数不可以声明为虚函数,同时也不能被const 和 volatile关键字修饰,因为static 本身就不属于类虚函数依靠vptr和vtable来处理。vptr是一个指针,在类的构造函数中创建生成,并且只能用this指针来访问它,静态成员函数没有this指针,所以无法访问vptr。

5、为什么构造函数不可以为虚函数?

尽管虚函数表vtable是在编译阶段就已经建立的,但指向虚函数表的指针vptr是在运行阶段实例化对象时才产生的。 如果类含有虚函数,编译器会在构造函数中添加代码来创建vptr。 问题来了,如果构造函数是虚的,那么它需要vptr来访问vtable,可这个时候vptr还没产生。 因此,构造函数不可以为虚函数。

我们之所以使用虚函数,是因为需要在信息不全的情况下进行多态运行。而构造函数是用来初始化实例的,实例的类型必须是明确的。 因此,构造函数没有必要被声明为虚函数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值