38.【C++ 虚函数 纯虚函数 虚基类 (最全详解)】(一)

简介: 38.【C++ 虚函数 纯虚函数 虚基类 (最全详解)】

(一)、虚函数

1.什么是虚函数:

虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参类型。以实现统一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数

2.虚函数的格式:

class Student
{
virtual void show(){}
}
class Student1 :public Student
{
  void show(){}
}

3.关于虚函数的注意事项:

1、 必须把动态联编的行为定义为类的虚函数。  

2、类之间存在父子类型关系,一般表现为一个类从另一个类公有派生而来。 

3、 必须先使用基类指针或者引用指向子类型的对象,然后直接或者间接使用基类指针调用虚函数

4.虚函数的作用:

可以让成员函数操作一般化用基类的指针指向不同的派生类的对象时,基类指针调用其虚成员函数,则会调用其真正指向对象的成员函数

而不是基类中定义的成员函数(只要派生类改写了该成员函数)。

若不是虚函数,则不管基类指针指向的哪个派生类对象,调用时都
会调用基类中定义的那个函数。

5.虚函数访问格式

指针变量->成员函数

6.虚函数的各种疑难杂症

【当指针是基类、但虚函数不在基类时】

代码展示:
#include <iostream>
using namespace std;
class A
{
public:
   void fun() { cout << "调用了A" << endl; }
};
class B:public A
{
public:
  void fun() { cout << "调用了B" << endl; }
};
class C:public A
{
public:
  virtual void fun() { cout << "调用了C" << endl; }
};
int main()
{
  A a,*p;
  B b;
  C c;
  p = &c;
  p->fun();
}
效果展示:

【当指针在派生类,虚函数在基类,指向派生类】

代码展示:
#include <iostream>
using namespace std;
class A
{
public:
   virtual void fun() { cout << "调用了A" << endl; }
};
class B:public A
{
public:
  void fun() { cout << "调用了B" << endl; }
};
class C:public A
{
public:
   void fun() { cout << "调用了C" << endl; }
};
int main()
{
  A a;
  B b;
  C c,*p;
  p = &c;
  p->fun();
}
效果展示:

1.【基类和派生类都为虚函数,指针在基类指向派生类】

父类的与子类的同名虚函数,在继承的时候,子类会将父类的覆盖,

代码展示:
#include <iostream>
using namespace std;
class A
{
public:
   virtual void fun() { cout << "调用了A" << endl; }
};
class B:public A
{
public:
  void fun() { cout << "调用了B" << endl; }
};
class C:public A
{
public:
  virtual void fun() { cout << "调用了C" << endl; }
};
int main()
{
  A a,*p;
  B b;
  C c;
  p = &c;
  p->fun();
}
效果展示:

2.【基类和派生类都有虚函数,指针在基类指向基类】

代码展示:
#include <iostream>
using namespace std;
class A
{
public:
  virtual void fun() { cout << "调用了A" << endl; }
};
class B :public A
{
public:
  void fun() { cout << "调用了B" << endl; }
};
class C :public A
{
public:
  virtual void fun() { cout << "调用了C" << endl; }
};
int main()
{
  A a, * p;
  B b;
  C c;
  p = &a;
  p->fun();
}
效果展示:

3.【基类和派生类都有虚函数,指针在派生类指向派生类】

代码展示:
#include <iostream>
using namespace std;
class A
{
public:
   virtual void fun() { cout << "调用了A" << endl; }
};
class B:public A
{
public:
  void fun() { cout << "调用了B" << endl; }
};
class C:public A
{
public:
  virtual void fun() { cout << "调用了C" << endl; }
};
int main()
{
  A a;
  B b;
  C c,*p;
  p = &c;
  p->fun();
}
效果展示:

4.【基类和派生类都有虚函数,指针在派生类指向基类】

错误分析:派生类访问不到基类

代码展示:
#include <iostream>
using namespace std;
class A
{
public:
  virtual void fun() { cout << "调用了A" << endl; }
};
class B :public A
{
public:
  void fun() { cout << "调用了B" << endl; }
};
class C :public A
{
public:
  virtual void fun() { cout << "调用了C" << endl; }
};
int main()
{
  A a;
  B b;
  C c,*p;
  p = &a;
  p->fun();
}
效果展示:

7.虚函数的示范

【非虚函数的调用,会适当其反】

代码展示:
#include <iostream>
using namespace std;
class A
{
private:
 int number;
public:
 A(int nu=21032114) :number(nu) {}
  void show()
 {
  cout << "基类,学号为:" << number<<endl;
 }
};
class B:public A
{
private:
 int score;
public:
 B(int sc = 86) :score(sc) {}
 void show()
 {
  cout << "派生,成绩为:" << score<<endl;
 }
};
int main()
{
 A a;
 a.show();
 B b;
 b.show();
 A* p;          
 p = &b;
 p->show(); //我想调用派生类,但仍然是基类的函数
 A& p1 = b;    
 b.show();
 return 0;
}
效果展示:


相关文章
|
7月前
|
C++
C++一分钟之-虚函数与抽象类
【6月更文挑战第21天】在C++中,虚函数与抽象类是多态的基础,增进类间耦合与灵活性。虚函数实现动态绑定,抽象类定义不可实例化的接口。关键点包括:记得使用`virtual`,避免滥用虚函数,确保派生类实现纯虚函数。抽象类不能直接实例化,派生类必须实现所有纯虚函数。通过实例代码学习和实践,能更好地掌握这些概念以优化代码设计。
62 2
|
15天前
|
Serverless 编译器 C++
【C++面向对象——类的多态性与虚函数】计算图像面积(头歌实践教学平台习题)【合集】
本任务要求设计一个矩形类、圆形类和图形基类,计算并输出相应图形面积。相关知识点包括纯虚函数和抽象类的使用。 **目录:** - 任务描述 - 相关知识 - 纯虚函数 - 特点 - 使用场景 - 作用 - 注意事项 - 相关概念对比 - 抽象类的使用 - 定义与概念 - 使用场景 - 编程要求 - 测试说明 - 通关代码 - 测试结果 **任务概述:** 1. **图形基类(Shape)**:包含纯虚函数 `void PrintArea()`。 2. **矩形类(Rectangle)**:继承 Shape 类,重写 `Print
40 4
|
15天前
|
设计模式 IDE 编译器
【C++面向对象——类的多态性与虚函数】编写教学游戏:认识动物(头歌实践教学平台习题)【合集】
本项目旨在通过C++编程实现一个教学游戏,帮助小朋友认识动物。程序设计了一个动物园场景,包含Dog、Bird和Frog三种动物。每个动物都有move和shout行为,用于展示其特征。游戏随机挑选10个动物,前5个供学习,后5个用于测试。使用虚函数和多态实现不同动物的行为,确保代码灵活扩展。此外,通过typeid获取对象类型,并利用strstr辅助判断类型。相关头文件如&lt;string&gt;、&lt;cstdlib&gt;等确保程序正常运行。最终,根据小朋友的回答计算得分,提供互动学习体验。 - **任务描述**:编写教学游戏,随机挑选10个动物进行展示与测试。 - **类设计**:基类
27 3
|
8月前
|
C++
C++程序中的纯虚函数
C++程序中的纯虚函数
66 0
|
5月前
|
编译器 C++ 索引
C++虚拟成员-虚函数
C++虚拟成员-虚函数
|
6月前
|
Java 编译器 程序员
C++中的语法知识虚继承和虚基类
**C++中的多继承可能导致命名冲突和数据冗余,尤其在菱形继承中。为解决这一问题,C++引入了虚继承(virtual inheritance),确保派生类只保留虚基类的一份实例,消除二义性。虚继承通过`virtual`关键字指定,允许明确访问特定路径上的成员,如`B::m_a`或`C::m_a`。这样,即使基类在继承链中多次出现,也只有一份成员副本,简化了内存布局并避免冲突。虚继承应在需要时提前在继承声明中指定,影响到从虚基类派生的所有后代类。**
|
8月前
|
Serverless C++
C++多态性、虚函数、纯虚函数和抽象类知识网络构造
C++多态性、虚函数、纯虚函数和抽象类知识网络构造
|
8月前
|
数据安全/隐私保护 C++
C++中的虚函数、纯虚函数与函数重写的技术性探讨
C++中的虚函数、纯虚函数与函数重写的技术性探讨
101 0
|
8月前
|
编译器 C++
C++的虚函数
C++的虚函数
47 0
|
15天前
|
C++ 芯片
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
56 19