虚函数是C++中实现多态的一种机制,它允许通过基类指针或引用来调用派生类的成员函数。虚函数的作用是实现动态绑定,即在运行时根据对象的实际类型来确定调用哪个函数。虚函数的声明方式是在函数前加上关键字virtual,如:
class Base {
public:
virtual void func(); // 声明一个虚函数
};
虚函数可以有以下几种场景用到:
class Base {
public:
virtual void func(); // 声明一个虚函数
};
虚函数可以在派生类中被override,也就是用不同的实现来替换基类的实现。如果派生类没有override虚函数,那么就会继承基类的实现。虚函数的作用是实现动态绑定,即在运行时根据对象的实际类型来确定调用哪个函数。例如,我们可以定义一个Shape类,为所有图形提供一个虚函数area(),然后让不同的派生类如Circle、Rectangle等override这个虚函数,实现各自的面积计算方法。这样,我们就可以通过一个Shape指针或引用来调用任何图形的area()函数,而不需要知道它们的具体类型。
class Base {
public:
virtual void func() = 0; // 声明一个纯虚函数
};
纯虚函数没有默认的实现,它要求任何派生类都必须提供自己的实现方法。如果派生类没有提供纯虚函数的实现,那么这个派生类也不能被实例化。纯虚函数的作用是定义一个接口,规范派生类的行为。例如,我们可以定义一个Animal类,为所有动物提供一个纯虚函数makeSound(),然后要求所有派生类如Dog、Cat等必须实现这个纯虚函数,提供各自的叫声方法。这样,我们就可以通过一个Animal指针或引用来调用任何动物的makeSound()函数,而不需要知道它们的具体类型。
虚函数和纯虚函数的区别主要有以下几点:
虚函数和纯虚函数的使用场景主要有以下几种:
C++中的深拷贝和浅拷贝是指在对象复制时,对于类中的资源(如动态内存、文件句柄等)的处理方式。具体来说:
下面是一个简单的例子来说明深拷贝和浅拷贝的区别:
#include
using namespace std;
class Person {
public:
// 有参构造函数
Person(int age, int height) {
m_age = age;
m_height = new int(height); // 动态分配内存
}
// 拷贝构造函数
Person(const Person& p) {
m_age = p.m_age;
// m_height = p.m_height; // 浅拷贝
m_height = new int(*p.m_height); // 深拷贝
}
// 析构函数
~Person() {
if (m_height != NULL) {
delete m_height; // 释放内存
m_height = NULL;
}
}
// 打印信息
void show() {
cout << "age: " << m_age << ", height: " << *m_height << endl;
}
private:
int m_age; // 年龄
int* m_height; // 身高
};
int main() {
Person p1(18, 180); // 创建一个Person对象
p1.show(); // 打印信息
Person p2(p1); // 用p1初始化p2,调用拷贝构造函数
p2.show(); // 打印信息
*p2.m_height = 190; // 修改p2的身高
p2.show(); // 打印信息
p1.show(); // 打印信息
return 0;
}
如果使用浅拷贝,那么输出结果为:
age: 18, height: 180
age: 18, height: 180
age: 18, height: 190
age: 18, height: 190
可以看到,修改p2的身高也影响了p1的身高,这是因为p1和p2共享了同一块内存。另外,在析构函数中释放内存时,也会出现重复释放或野指针的问题。
如果使用深拷贝,那么输出结果为:
age: 18, height: 180
age: 18, height: 180
age: 18, height: 190
age: 18, height: 180
可以看到,修改p2的身高不影响p1的身高,这是因为p1和p2各自拥有了独立的内存。另外,在析构函数中释放内存时,也不会出现问题。