C++中的虚函数、纯虚函数与函数重写的技术性探讨

简介: C++中的虚函数、纯虚函数与函数重写的技术性探讨

一、引言

在C++面向对象编程中,虚函数(Virtual Functions)和纯虚函数(Pure Virtual Functions)是两个核心概念,它们为实现多态性提供了基础。同时,函数重写(Function Overriding)是面向对象编程中子类对父类函数进行重新定义的一种技术。本文将详细探讨这些概念,包括它们的定义、用法以及在实际编程中的应用。

二、虚函数

定义

虚函数是在基类中声明并在一个或多个派生类中被重新定义的成员函数。在基类中使用virtual关键字进行声明,以表明该函数可以在派生类中被重写。

cpp

 

class Base {

 

public:

 

virtual void function() {

 

// 基类实现

 

std::cout << "Base function called." << std::endl;

 

}

 

};

 

 

 

class Derived : public Base {

 

public:

 

void function() override { // override是可选的,但建议使用以提供额外的清晰度

 

// 派生类实现

 

std::cout << "Derived function called." << std::endl;

 

}

 

};

用途

虚函数的主要用途是实现多态性。通过基类指针或引用指向派生类对象,并调用虚函数时,将执行与指针或引用所指向的对象类型相对应的派生类中的函数版本。这允许在运行时动态地确定要调用的函数版本。

cpp

 

Base* ptr = new Derived();

 

ptr->function(); // 输出 "Derived function called."

 

delete ptr;

三、纯虚函数

定义

纯虚函数是在基类中声明的虚函数,但它没有定义(只有声明)。在函数声明的结尾使用= 0来指示该函数是纯虚函数。包含纯虚函数的类被称为抽象类(Abstract Class),抽象类不能被实例化。

cpp

 

class AbstractBase {

 

public:

 

virtual void pureVirtualFunction() = 0; // 纯虚函数

 

};

 

 

 

class Derived : public AbstractBase {

 

public:

 

void pureVirtualFunction() override {

 

// 派生类实现

 

std::cout << "Derived pure virtual function called." << std::endl;

 

}

 

};

用途

纯虚函数用于定义接口,指定派生类必须实现的函数。通过继承抽象类并提供纯虚函数的实现,派生类可以创建具有特定行为的对象。这有助于实现代码重用和模块化设计。

四、函数重写

定义

函数重写(也称为函数覆盖)是指派生类中存在一个与基类虚函数同名、同参数列表、同返回类型的函数,并且该函数在派生类中使用override(可选)关键字进行声明。这样,当使用基类指针或引用指向派生类对象并调用该函数时,将执行派生类中的函数版本。

cpp

 

class Base {

 

public:

 

virtual void function() {

 

// ...

 

}

 

};

 

 

 

class Derived : public Base {

 

public:

 

void function() override { // 使用override关键字

 

// ...

 

}

 

};

注意事项

· 派生类重写的函数必须与基类中的虚函数具有相同的名称、参数列表和返回类型(协变返回类型除外)。

· 重写函数不能具有比基类函数更严格的访问控制(例如,基类函数为public,派生类函数不能为privateprotected)。

· 如果基类函数不是虚函数,派生类中的同名函数将隐藏基类函数,而不是重写它。这可能会导致意外的行为,因此应始终将打算被重写的函数声明为虚函数。

五、总结

虚函数、纯虚函数和函数重写是C++面向对象编程中的核心概念,它们为实现多态性和代码重用提供了强大的支持。通过正确地使用这些技术,我们可以创建灵活、可扩展和可维护的软件系统。在实际编程中,应根据具体需求选择是否使用虚函数和纯虚函数,并遵循函数重写的规则来确保代码的正确性和可读性。

 

目录
相关文章
|
21天前
|
存储 分布式数据库 API
技术好文:VisualC++查看文件被哪个进程占用
技术好文:VisualC++查看文件被哪个进程占用
|
15天前
|
存储 C++
【C++】string类的使用③(非成员函数重载Non-member function overloads)
这篇文章探讨了C++中`std::string`的`replace`和`swap`函数以及非成员函数重载。`replace`提供了多种方式替换字符串中的部分内容,包括使用字符串、子串、字符、字符数组和填充字符。`swap`函数用于交换两个`string`对象的内容,成员函数版本效率更高。非成员函数重载包括`operator+`实现字符串连接,关系运算符(如`==`, `&lt;`等)用于比较字符串,以及`swap`非成员函数。此外,还介绍了`getline`函数,用于按指定分隔符从输入流中读取字符串。文章强调了非成员函数在特定情况下的作用,并给出了多个示例代码。
|
15天前
|
算法 C++ 容器
|
15天前
|
存储 编译器 程序员
|
16天前
|
存储 编译器 文件存储
|
20天前
|
编译器 C++
【C++】类和对象③(类的默认成员函数:赋值运算符重载)
在C++中,运算符重载允许为用户定义的类型扩展运算符功能,但不能创建新运算符如`operator@`。重载的运算符必须至少有一个类类型参数,且不能改变内置类型运算符的含义。`.*::sizeof?`不可重载。赋值运算符`=`通常作为成员函数重载,确保封装性,如`Date`类的`operator==`。赋值运算符应返回引用并检查自我赋值。当未显式重载时,编译器提供默认实现,但这可能不足以处理资源管理。拷贝构造和赋值运算符在对象复制中有不同用途,需根据类需求定制实现。正确实现它们对避免数据错误和内存问题至关重要。接下来将探讨更多操作符重载和默认成员函数。
|
20天前
|
程序员 编译器 C++
探索C++语言宝库:解锁基础知识与实用技能(类型变量+条件循环+函数模块+OOP+异常处理)
探索C++语言宝库:解锁基础知识与实用技能(类型变量+条件循环+函数模块+OOP+异常处理)
16 0
|
21天前
|
SQL 人工智能 算法
技术心得记录:模板函数函数模板FunctionTemplate(C++Primer
技术心得记录:模板函数函数模板FunctionTemplate(C++Primer