C++ 类成员函数与虚函数

本文探讨了C++中哪些类成员函数不能成为虚函数,如构造函数、static成员函数和内联函数,并详细解释了原因。同时强调了当类作为基类时,析构函数必须为虚函数的重要性,以确保正确地销毁派生类对象,避免内存泄漏问题。通过代码示例,展示了不使用虚析构函数可能导致的问题及启用虚析构函数后的正确行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么类成员函数不能成为虚函数

  • 构造函数,虚函数是运行时多态,必须根据对象类型动态绑定。而调用构造函数时还不存在对象。
  • static成员函数,属于一个类,而不特属于某个对象,因此不能是虚函数。
  • 内联函数,内联在编译时展开,而虚函数是运行时动态绑定。

什么类成员函数必须成为虚函数

  • 当一个类作为基类时,其析构函数必须是虚函数,否则可能没办法正确析构其派生类

看以下几段代码:

#include<iostream>
using namespace std;
class Base{
public:
    Base() {};
    ~Base() {cout << "Output from the destructor of class Base!" << endl;};

    void DoSomething() { cout << "Do something in class Base!" << endl; };
};

class Derived : public Base{
public:
    Derived() {};
    ~Derived() { cout << "Output from the destructor of class Derived!" << endl; };

    void DoSomething() { cout << "Do something in class Derived!" << endl; };
};
int main(){  
  Derived *p =  new Derived;
  p->DoSomething();
  delete p;
  return 0;
}

在上述代码中,我们new了一个派生对象,析构时会先调用派生类析构函数,再调用基类析构函数,不存在内存泄漏问题。
输出如下
在这里插入图片描述
再看一段代码,与上一段代码仅在main函数段有区别:

#include<iostream>
using namespace std;
class Base {
public:
	Base() {};
	~Base() { cout << "Output from the destructor of class Base!" << endl; };

	void DoSomething() { cout << "Do something in class Base!" << endl; };
};

class Derived : public Base {
public:
	Derived() {};
	~Derived() { cout << "Output from the destructor of class Derived!" << endl; };

	void DoSomething() { cout << "Do something in class Derived!" << endl; };
};
int main() {
	Base *p = new Derived;
	p->DoSomething();
	delete p;
	return 0;
}

上述代码是一种常见的动态绑定方法——基类指针指向派生类对象。
输出如下,可见其没有调用派生类析构函数,可能发生内存泄漏:
在这里插入图片描述
在基类析构前加上virtual,再看看输出结果:
在这里插入图片描述
这就是在类作为基类时,其析构函数需要成为虚函数的原因。换言之,若不作为基类,则没有必要加virtual,否则会带来对象数 * 指针大小的额外空间开销

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值