C++ 虚函数与纯虚函数的区别
了解虚函数和纯虚函数在C++中的区别之前,我们应该了解C++中的虚函数和纯虚函数。
什么是虚函数
虚函数是在基类中声明并可以由派生类重新定义的成员函数。
让我们通过一个示例来理解。
#include
using namespace std;
class base
{
public:
void show()
{
std::cout << "Base class" << std::endl;
}
};
class derived1 : public base
{
public:
void show()
{
std::cout << "Derived class 1" << std::endl;
}
};
class derived2 : public base
{
public:
void show()
{
std::cout << "Derived class 2" << std::endl;
}
};
int main()
{
base *b;
derived1 d1;
derived2 d2;
b=&d1
b->show();
b=&d2
b->show();
return 0;
}
在上面的代码中,我们没有使用虚函数。我们创建了一个包含show()函数的基类。还创建了名为 ‘derived1’ 和 ‘derived2′ 的两个类,它们继承了基类的属性。’derived1’ 和 ‘ derived2’ 类都重新定义了show()函数。在main()方法中,声明了一个类为base的指针变量’b’。derived1和derived2的对象分别为d1和d2。尽管’b’包含d1和d2的地址,但是调用show()方法时,它始终调用基类的show()方法,而不是调用derived1和derived2类的函数。
为了解决上述问题,我们需要在基类中将方法声明为虚方法。在这里,虚表示该方法实际上不存在。我们可以通过在函数之前添加virtual关键字来将方法声明为虚方法。在上面的程序中,我们需要在基类中的show()函数之前添加virtual关键字,如下所示:
virtual void show()
{
std::cout << "Base class" << std::endl;
}
一旦以上更改完成,输出将为:
重要点:
- 它是运行时多态。
- 基类和派生类具有相同的函数名,并且基类被分配为派生类对象的地址,指针仍将执行基类函数。
- 如果函数被声明为虚函数,编译器将根据指向基类指针的分配地址在运行时确定要执行的函数。
什么是纯虚函数
纯虚函数是在类中没有定义的虚函数。让我们通过一个示例理解纯虚函数的概念。
在以上图示表示中,shape是基类,而rectangle、square和circle是派生类。由于我们没有为虚函数提供任何定义,因此它会自动转换为纯虚函数。
纯虚函数的特点
- 纯虚函数是一个“什么也不做”的函数。这里的“什么也不做”意味着它只提供模板,派生类实现函数。
- 它可以被视为空函数,意味着纯虚函数相对于基类没有任何定义。
- 程序员需要在派生类中重新定义纯虚函数,因为基类中没有定义。
- 拥有纯虚函数的类不能用于创建自己的直接对象。这意味着如果类中包含任何纯虚函数,我们不能创建该类的对象。这种类型的类被称为抽象类。
语法
创建虚函数有两种方式:
virtual void display() = 0;
或
virtual void display() {}
让我们通过一个示例来理解。
#include
using namespace std;
// Abstract class
class Shape
{
public:
virtual float calculateArea() = 0; // pure virtual function.
};
class Square : public Shape
{
float a;
public:
Square(float l)
{
a = l;
}
float calculateArea()
{
return a*a;
}
};
class Circle : public Shape
{
float r;
public:
Circle(float x)
{
r = x;
}
float calculateArea()
{
return 3.14*r*r ;
}
};
class Rectangle : public Shape
{
float l;
float b;
public:
Rectangle(float x, float y)
{
l=x;
b=y;
}
float calculateArea()
{
return l*b;
}
};
int main()
{
Shape *shape;
Square s(3.4);
Rectangle r(5,6);
Circle c(7.8);
shape =&s
int a1 =shape->calculateArea();
shape = &r
int a2 = shape->calculateArea();
shape = &c
int a3 = shape->calculateArea();
std::cout << "Area of the square is " <
虚函数和纯虚函数之间的区别
虚函数 | 纯虚函数 |
---|---|
虚函数是一个在基类中定义的成员函数,在派生类中可以重新定义。 | 纯虚函数是一个在基类中声明的成员函数,在派生类中实现。 |
包含虚函数的类不是抽象类。 | 包含纯虚函数的类是抽象类。 |
对于虚函数,函数的定义在基类中提供。 | 对于纯虚函数,函数的定义在基类中不提供。 |
包含虚函数的基类可以实例化。 | 包含纯虚函数的基类变成抽象类,无法实例化。 |
如果派生类不重新定义基类的虚函数,编译不受影响。 | 如果派生类不定义纯虚函数,不会发生错误,但派生类变成抽象类。 |
所有派生类可以选择是否重新定义虚函数。 | 所有派生类必须定义纯虚函数。 |