提交 1b615c06 编写于 作者: W wizardforcel

2019-08-27 10:12:02

上级 8c54d0eb
# C++中的虚函数:运行时多态
# C++ 中的虚函数:运行时多态
> 原文: [https://beginnersbook.com/2017/09/cpp-virtual-functions-runtime-polymorphism/](https://beginnersbook.com/2017/09/cpp-virtual-functions-runtime-polymorphism/)
在本指南中,我们将看到**什么是虚函数以及我们使用它们的原因**。当我们在一个类中将一个函数声明为虚函数时,所有覆盖此函数的子类默认情况下它们的函数实现为虚函数(无论它们是否标记为虚拟)。 **为什么我们声明一个虚函数?** 让编译器知道需要在运行时解析对此函数的调用(也称为**后期绑定**和动态链接),以便确定对象类型并且函数的正确版本是调用
在本指南中,我们将看到**什么是虚函数以及我们使用它们的原因**。当我们在一个类中将一个函数声明为虚函数时,所有覆盖此函数的子类默认情况下的函数实现为虚函数(无论它们是否标记为虚拟)
让我们举个例子来理解当我们不将[重写函数](https://beginnersbook.com/2017/09/cpp-function-overriding/)标记为虚拟时会发生什么。
**为什么我们声明一个虚函数?**
让编译器知道需要在运行时解析对此函数的调用(也称为**晚期绑定**和动态链接),以便确定对象类型并且调用函数的正确版本。
让我们举个例子来理解当我们不将[覆盖函数](https://beginnersbook.com/2017/09/cpp-function-overriding/)标记为虚拟时会发生什么。
## 示例 1:覆盖非虚函数
在这里看到问题。即使我们有父类指针指向子类的实例(对象),也会调用该函数的父类版本。
在这里看到问题。即使我们指向子类的实例(对象)的父类指针,也会调用该函数的父类版本。
您可能在想我为什么创建指针,我可以简单地创建子类的对象,如下所示:`Dog obj`;并将`Dog`实例分配给它。好吧,在这个例子中我只有一个子类,但是当我们有一个包含多个子类的大项目时,不建议单独创建子类的对象,因为它增加了复杂性并且代码容易出错。在此示例之后更加清晰。
您可能在想我为什么创建指针,我可以简单地创建子类的对象,如下所示:`Dog obj;`并将`Dog`实例分配给它。好吧,在这个例子中我只有一个子类,但是当我们有一个包含多个子类的大项目时,不建议单独创建子类的对象,因为它增加了复杂性并且代码容易出错。在此示例之后更加清晰。
```cpp
#include<iostream>
......
......@@ -2,17 +2,19 @@
> 原文: [https://beginnersbook.com/2017/09/cpp-encapsulation/](https://beginnersbook.com/2017/09/cpp-encapsulation/)
封装是将数据成员和函数组合在一个称为类的单个单元中的过程。这是为了防止直接访问数据,通过类的功能提供对它们的访问。它是[面向对象编程(OOP)](https://beginnersbook.com/2017/08/cpp-oops-concepts/)的流行功能之一,它有助于**数据隐藏**
封装是将数据成员和函数组合在一个称为类的单个单元中的过程。这是为了防止直接访问数据,通过类的函数提供对它们的访问。它是[面向对象编程(OOP)](https://beginnersbook.com/2017/08/cpp-oops-concepts/)的流行特性之一,它有助于**数据隐藏**
## 如何在类上实现封装
为此:
1)将所有数据成员设为私有。
2)为每个数据成员创建公共设置器和获取器函数,使设置函数设置数据成员的值并获取函数获取数据成员的值。
2)为每个数据成员创建公共设置器和获取器函数,使设置器设置数据成员的值,获取器获取数据成员的值。
让我们在一个示例程序中看到这个:
## C++中的封装示例
## C++ 中的封装示例
这里我们有两个数据成员`num``ch`,我们已将它们声明为私有,因此它们在类外无法访问,这样我们就隐藏了数据。获取和设置这些数据成员的值的唯一方法是通过公共设置器和获取器函数。
......
# C++中的接口:抽象类
# C++ 中的接口:抽象类
> 原文: [https://beginnersbook.com/2017/09/cpp-abstract-class/](https://beginnersbook.com/2017/09/cpp-abstract-class/)
[C++](https://beginnersbook.com/2017/08/c-plus-plus-tutorial-for-beginners/) 中,我们使用术语抽象类和接口可互换。具有**纯虚函数**的类称为抽象类。例如,以下函数是纯虚函数:
[C++](https://beginnersbook.com/2017/08/c-plus-plus-tutorial-for-beginners/) 中,我们互换使用术语抽象类和接口。具有**纯虚函数**的类称为抽象类。例如,以下函数是纯虚函数:
```cpp
virtual void fun() = 0;
......@@ -12,11 +12,11 @@ virtual void fun() = 0;
## 为什么我们需要一个抽象类?
让我们借助现实生活中的例子来理解这一点。让我们说我们有一个类`Animal`动物睡眠,动物发出声音等等。现在我只考虑这两个行为并创建一个具有两个函数`sound()``sleeping()`的类 Animal
让我们借助现实生活中的例子来理解这一点。让我们说我们有一个类`Animal`它会睡眠,发出声音等等。现在我只考虑这两个行为并创建一个具有两个函数`sound()``sleeping()`的类`Animal`
现在,我们知道动物的声音是不同的猫说“喵”,狗说“汪”。那么我在`Animal`类中为函数`sound()`提供了什么实现,这样做的唯一和正确的方法是使这个函数纯粹抽象,这样我就不需要在`Animal`类中给出实现但是所有继承`Animal`的类必须为此函数提供实现。这样我确保所有动物都有声音,但它们有独特的声音。
现在,我们知道动物的声音是不同的,猫说“喵”,狗说“汪”。那么我在`Animal`类中为函数`sound()`提供了什么实现?这样做的唯一和正确的方法是使这个函数纯粹抽象,这样我就不需要在`Animal`类中给出实现但是所有继承`Animal`的类必须为此函数提供实现。这样我确保所有动物都有声音,但它们有独特的声音。
可以在 C++程序中编写相同的示例,如下所示:
可以在 C++ 程序中编写相同的示例,如下所示:
## 抽象类示例
......@@ -50,8 +50,10 @@ int main(){
## 抽象类规则
1)我们已经看到任何具有**纯虚函数**的类都是抽象类。
2)我们无法创建抽象类的实例。例如:如果我在上面的程序中写了这行`Animal obj;`,就会导致编译错误。
3)我们可以创建指针和基本抽象类的引用指向子类的实例。例如,这是有效的:
3)我们可以创建指向子类的实例的抽象基类的指针和引用。例如,这是有效的:
```cpp
Animal *obj = new Dog();
......@@ -59,4 +61,5 @@ obj->sound();
```
4)抽象类可以有[构造函数](https://beginnersbook.com/2017/08/cpp-constructors/)
5)如果派生类没有实现父类的纯虚函数,则派生类变为抽象类。
\ No newline at end of file
# 从 C++中的函数传递和返回对象
# 从 C++ 中的函数传递和返回对象
> 原文: [https://beginnersbook.com/2017/09/cpp-pass-and-return-object-from-a-function/](https://beginnersbook.com/2017/09/cpp-pass-and-return-object-from-a-function/)
......@@ -6,7 +6,7 @@
## 将对象传递给函数
可以将对象传递给函数,就像我们[将结构传递给函数](https://beginnersbook.com/2017/09/cpp-structure-and-function/)一样。在`A`类中,我们有一个函数`disp()`,我们在其中传递类`A`的对象。类似地,我们可以将一个类的对象传递给不同类的函数。
可以将对象传递给函数,就像我们[将结构传递给函数](https://beginnersbook.com/2017/09/cpp-structure-and-function/)一样。在`A`类中,我们有一个函数`disp()`,我们在其中传递类`A`的对象。类似地,我们可以将一个类的对象传递给不同类的函数。
```cpp
#include <iostream>
......
# C++中的友元类和友元函数
# C++ 中的友元类和友元函数
> 原文: [https://beginnersbook.com/2017/09/friend-class-and-friend-functions/](https://beginnersbook.com/2017/09/friend-class-and-friend-functions/)
我们知道一个类无法访问其他类的私有成员。类似地,不继承另一个类的类不能访问其受保护的成员。
**友元类:**
**友元类**是一个类,可以访问被声明为**友元**的类的私有成员和受保护成员。当我们想要允许特定类访问类的私有成员和受保护成员时,这是必需的。
## 函数类示例
......@@ -48,8 +49,8 @@ A
11
```
**
友元函数:**
**友元函数:**
与友元类相似,此函数可以访问另一个类的私有和受保护成员。全局函数也可以声明为友元,如下例所示:
## 友元函数示例
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册