【C++ 语言】面向对象 ( 继承 | 重写 | 子类调用父类方法 | 静态多态 | 动态多态 | 虚函数 | 纯虚函数 )(二)

简介: 【C++ 语言】面向对象 ( 继承 | 重写 | 子类调用父类方法 | 静态多态 | 动态多态 | 虚函数 | 纯虚函数 )(二)

虚函数


1 . 静态多态 : 在编译时 , 就可以确定函数调用的地址 ; 上面 多态 中的示例就是静态多态示例 ;


下面的虚函数的示例 , 是动态多态示例 ;


2 . 动态多态 : 在运行时 , 确定函数调用地址 , 这里就用到虚函数 ;


3 . 虚函数作用 : 让函数调用的地址 , 在运行时确定调用哪个函数 ;


4. 虚函数解析 : 在对象调用虚函数方法时 , 系统会查看该对象真正类型是什么类型 , 然后去调用对应类型的方法 ; 对象是使用什么类型的构造函数创建的 , 其真正的类型就是这个类型 , 因此最终调用该类中的虚函数方法 ;


5. 虚函数使用要点 :


1. 构造方法 : 不能设置成虚函数, 如果将构造方法设置成虚函数 , 编译时会报错 ;

2. 析构方法 : 必须设置成虚函数 , 释放子类对象内存时 , 必须释放子类对象的内存 , 否则子类对象的内存永远不会被释放 ;

3. 没有子类 : 虚函数在子类继承父类时才有意义 , 根据类型动态判定该调用哪个方法 , 如果一个类没有子类 , 其设置成虚函数没有意义 , 但也不影响程序运行 ;



虚函数示例


虚函数代码示例解析 :


1. 父类中定义虚函数 :

//父类
class Parent{
public:
  void parent_method() {
  cout << " Parent parent_method " << endl;
  }
  //虚函数
  virtual void virtual_method() {
  cout << " Parent virtual_method " << endl;
  }
};


2. 子类中重写虚函数 :

//子类
//继承父类 Parent
//继承作用域 : 默认私有继承 private 
class Child : public Parent, public Parent1 {
public:
  void parent_method() {
  //子类中调用父类的方法 , 该操作相当于 Java 中的 super 方法 
  Parent::parent_method();
  Parent1::parent_method();
  cout << " Child parent_method " << endl;
  }
  //重写父类的虚函数
  void virtual_method() {
  cout << " Child virtual_method " << endl;
  }
};


3. 调用虚函数 :

//在栈内存中创建一个 Child 对象, 并调用其重写的父类的方法
  Child child;
  //多态
  //声明 Parent1 父类对象 , 为其赋值一个 Child 对象
  Parent* parent = new Child();
  //静态多态 : 在编译时 , 就可以确定函数调用的地址 ; 
  //  此时调用其 parent_method 方法 , 调用的是父类的方法
  parent->parent_method();
  //动态多态 : 在运行时 , 确定函数调用地址 , 
  //  此处调用的是子类实现的方法
  parent->virtual_method();


4. 代码执行结果 :

Parent parent_method
 Child virtual_method


5. 结果分析 :

① 静态多态分析 : 第一次调用父类的 parent_method 方法 , 虽然子重写该方法 , 但是对象类型声明的是父类类型 , 其仍然调用父类方法 ;

② 动态多态分析 : 第二次调用父类的 virtual_method 方法 , 该方法时虚函数 , 子类重写了该虚函数 , 在函数调用的时候 , 会自动根据对象的类型判定调用哪个方法 , 该对象使用 new Child() 创建 , 其类型是 Child 类型 , 因此最终调用的是子类重写的方法 ;



纯虚函数


1. 纯虚函数 : 类似于 Java 的抽象方法 , 父类中声明后 , 该方法必须实现 , 否则编译时报错 ;


2. 代码示例 :


① 父类中定义纯虚函数 :


//父类
class Parent{
public:
  //纯虚函数 , 类似于 Java 的抽象方法 , 
  //父类中声明后 , 该方法必须实现 , 否则编译时报错
  virtual void pure_virtual_method() = 0;
};


② 子类中实现虚函数 :


//子类
//继承父类 Parent
class Child : public Parent {
public:
  //实现纯虚函数方法 , 该方法必须实现 , 否则会报错
  void pure_virtual_method() {
  cout << " Child pure_virtual_method " << endl;
  }
};


③ 调用子类中实现的纯虚函数 :


//在栈内存中创建一个 Child 对象, 并调用其重写的父类的方法
  Child child;
  //纯虚函数测试
  parent->pure_virtual_method();


④ 执行结果 :


Child pure_virtual_method



相关代码


1. 类的定义及继承相关代码 :


#pragma once
using namespace std;
//父类
class Parent{
public:
  void parent_method() {
  cout << " Parent parent_method " << endl;
  }
  //虚函数
  virtual void virtual_method() {
  cout << " Parent virtual_method " << endl;
  }
  //纯虚函数 , 类似于 Java 的抽象方法 , 
  //父类中声明后 , 该方法必须实现 , 否则编译时报错
  virtual void pure_virtual_method() = 0;
};
//父类
class Parent1 {
public:
  void parent_method() {
  cout << " Parent1 parent_method " << endl;
  }
  void parent_method1() {
  cout << " Parent1 parent_method1 " << endl;
  }
};
//子类
//继承父类 Parent
//继承作用域 : 默认私有继承 private 
class Child : public Parent, public Parent1 {
public:
  void parent_method() {
  //子类中调用父类的方法 , 该操作相当于 Java 中的 super 方法 
  Parent::parent_method();
  Parent1::parent_method();
  cout << " Child parent_method " << endl;
  }
  //重写父类的虚函数
  void virtual_method() {
  cout << " Child virtual_method " << endl;
  }
  //实现纯虚函数方法 , 该方法必须实现 , 否则会报错
  void pure_virtual_method() {
  cout << " Child pure_virtual_method " << endl;
  }
};




2. 调用上述方法 :


//在栈内存中创建一个 Child 对象, 并调用其重写的父类的方法
  Child child;
  //调用子类重写的父类的方法
  child.parent_method();
  //调用子类没有重写的父类方法
  child.parent_method1();
  //多态
  //声明 Parent1 父类对象 , 为其赋值一个 Child 对象
  Parent* parent = new Child();
  //静态多态 : 在编译时 , 就可以确定函数调用的地址 ; 
  //  此时调用其 parent_method 方法 , 调用的是父类的方法
  parent->parent_method();
  //动态多态 : 在运行时 , 确定函数调用地址 , 
  //  此处调用的是子类实现的方法
  parent->virtual_method();
  //纯虚函数测试
  parent->pure_virtual_method();


执行结果 :


Parent parent_method
 Parent1 parent_method
 Child parent_method
 Parent1 parent_method1
 Parent parent_method
 Child virtual_method
 Child pure_virtual_method


目录
相关文章
|
1月前
|
存储 编译器 数据安全/隐私保护
【C++】多态
多态是面向对象编程中的重要特性,允许通过基类引用调用派生类的具体方法,实现代码的灵活性和扩展性。其核心机制包括虚函数、动态绑定及继承。通过声明虚函数并让派生类重写这些函数,可以在运行时决定具体调用哪个版本的方法。此外,多态还涉及虚函数表(vtable)的使用,其中存储了虚函数的指针,确保调用正确的实现。为了防止资源泄露,基类的析构函数应声明为虚函数。多态的底层实现涉及对象内部的虚函数表指针,指向特定于类的虚函数表,支持动态方法解析。
32 1
|
2月前
|
编译器 C++
C++入门12——详解多态1
C++入门12——详解多态1
47 2
C++入门12——详解多态1
|
2月前
|
安全 程序员 编译器
【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则
【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则
91 11
|
2月前
|
C++
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
67 1
|
2月前
|
C++
C++入门13——详解多态2
C++入门13——详解多态2
88 1
|
3月前
|
存储 安全 编译器
【C++核心】一文理解C++面向对象(超级详细!)
这篇文章详细讲解了C++面向对象的核心概念,包括类和对象、封装、继承、多态等。
32 2
|
2月前
|
存储 编译器 C语言
【C++】初识面向对象:类与对象详解
【C++】初识面向对象:类与对象详解
|
4月前
|
存储 编译器 C++
|
28天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
49 2
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
98 5