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;
}
效果展示:


相关文章
|
5月前
|
C++
C++一分钟之-虚函数与抽象类
【6月更文挑战第21天】在C++中,虚函数与抽象类是多态的基础,增进类间耦合与灵活性。虚函数实现动态绑定,抽象类定义不可实例化的接口。关键点包括:记得使用`virtual`,避免滥用虚函数,确保派生类实现纯虚函数。抽象类不能直接实例化,派生类必须实现所有纯虚函数。通过实例代码学习和实践,能更好地掌握这些概念以优化代码设计。
51 2
|
6月前
|
C++
C++程序中的纯虚函数
C++程序中的纯虚函数
50 0
|
3月前
|
编译器 C++ 索引
C++虚拟成员-虚函数
C++虚拟成员-虚函数
|
4月前
|
Java 编译器 程序员
C++中的语法知识虚继承和虚基类
**C++中的多继承可能导致命名冲突和数据冗余,尤其在菱形继承中。为解决这一问题,C++引入了虚继承(virtual inheritance),确保派生类只保留虚基类的一份实例,消除二义性。虚继承通过`virtual`关键字指定,允许明确访问特定路径上的成员,如`B::m_a`或`C::m_a`。这样,即使基类在继承链中多次出现,也只有一份成员副本,简化了内存布局并避免冲突。虚继承应在需要时提前在继承声明中指定,影响到从虚基类派生的所有后代类。**
|
6月前
|
Serverless C++
C++多态性、虚函数、纯虚函数和抽象类知识网络构造
C++多态性、虚函数、纯虚函数和抽象类知识网络构造
|
6月前
|
C++ 开发者
C++程序中利用虚函数实现动态多态性
C++程序中利用虚函数实现动态多态性
57 2
|
6月前
|
数据安全/隐私保护 C++
C++中的虚函数、纯虚函数与函数重写的技术性探讨
C++中的虚函数、纯虚函数与函数重写的技术性探讨
91 0
|
6月前
|
编译器 C++
C++的虚函数
C++的虚函数
37 0
|
6月前
|
C++
C++|多态性与虚函数(2)|虚析构函数|重载函数|纯虚函数|抽象类
C++|多态性与虚函数(2)|虚析构函数|重载函数|纯虚函数|抽象类
|
5天前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
27 5