广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++虚函数注意事项
  • 408
分享到

C++虚函数注意事项

2024-04-02 19:04:59 408人浏览 八月长安
摘要

目录一、虚函数注意事项1.构造函数2.析构函数3.友元4.没有重新定义5.重新定义将隐藏方法文章转自公众号:Coder梁(ID:Coder_LT) 一、虚函数注意事项 在之前的文章当

文章转自公众号:Coder梁(ID:Coder_LT)

一、虚函数注意事项

在之前的文章当中,我们已经讨论了虚函数的使用方法,也对它的原理进行了简单的介绍。

这里简单做一个总结:

  • 在基类的方法声明中使用关键字virtual可以声明虚函数
  • 加上了virtual关键字的函数在基类以及派生类和派生类再派生出来的类中都是虚的
  • 在调用虚函数时,程序将会根据对象的类型执行对应的方法而非引用或指针的类型
  • 在定义基类时,需要将要在派生类中重新定义的类方法声明为虚,如析构函数

除了这些之外,我们还有一些其他需要注意的事项。

1.构造函数

构造函数不能是虚函数,创建派生类对象时将调用派生类的构造函数,而非基类的构造函数,毕竟构造函数是根据类名调用的。

一般我们会在派生类中调用基类的构造函数,这其实不是继承机制,所以将类构造函数声明为虚没有意义。

2.析构函数

前文说过析构函数应该是虚函数,除非类不被继承。

因为派生类当中往往含有独有的成员变量,如果析构函数非虚,那么会导致在对象析构时仅调用基类的析构函数,从而导致独有的成员变量内存不被释放,引起内存泄漏。

所以通常我们会将析构函数设置成virtual,即使不用做基类也不会引起错误,至多只会影响一点效率。但在大型合作开发项目当中,许多组件和类都是共享的,我们往往无法保证我们开发的类是否会被其他开发者继承,因此设置虚析构函数也是一种常规做法。

3.友元

友元函数不能是虚函数,因为友元不是类成员,只有成员函数才能是虚函数。

如果我们希望友元函数也能实现类似虚函数的功能, 我们可以在友元函数当中使用虚函数来解决。

4.没有重新定义

如果派生类当中没有重新定义虚函数,那么将使用该函数的基类版本。如果派生类位于派生链中,如B继承了A,C继承了B这种情况,那么派生类将会使用最新的虚函数版本。

5.重新定义将隐藏方法

我们来看一个例子:

class Mammal {
 private:
  string name;
 public:
  Mammal(string n): name(n) {}
  virtual void speak() const {
   cout << "can't say anything" << endl;
  }
};

class Human : public Mammal{
 private:
  string job;
 public:
  Human(string n, string j): Mammal(n), job(j) {}
  virtual void speak(const string st) const {
   cout << "i'm human" << endl;
  }
};

我们在父类当中定义了一个无参虚函数speak,而在子类Human当中也定义了一个需要传入一个string类型的虚函数speak

我试了一下,在我的g++编译器当中,会报错:

但根据c++ Primer中的说法,在一些古老的编译器当中,可能不会报错,甚至可能连警告都没有。

在这类编译器当中,我们重新定义父类中的虚函数,这样的重新定义不会生成两个重载版本,而是隐藏了父类无参的版本,只保留了接受string类型的版本,这种情况有别于函数重载。

在派生类当中重新定义函数,不是使用相同的函数特征标覆盖基类声明,而是隐藏同名的基类方法,不管函数特征标如何。

C++ Primer当中给出了两条经验规则:

如果重新定义继承的方法,应该保证与原来的原型完全相同,唯一的例外是返回的类型,如果基类返回的是基类的引用或指针,派生类可以改成派生类的引用或指针:

class Mammal {
 private:
  string name;
 public:
  Mammal(string n): name(n) {}
  virtual Mammal* build();
};

class Human : public Mammal{
 private:
  string job;
 public:
  Human(string n, string j): Mammal(n), job(j) {}
  virtual Human* build();
};

如果基类声明被重载了,那么应该在派生类中声明所有的基类版本:
 

class Mammal {
 private:
  string name;
 public:
  Mammal(string n): name(n) {}
  virtual void speak() const ;
     virtual void speak(int n) const;
     virtual void speak(const string st) const;
};

class Human : public Mammal{
 private:
  string job;
 public:
  Human(string n, string j): Mammal(n), job(j) {}
  virtual void speak() const ;
     virtual void speak(int n) const;
     virtual void speak(const string st) const;
};

如果我们只重新定义了一个版本,那么另外两个版本将隐藏。

但这可能和编译器版本有关,在新版的编译器当中似乎取消了这一设定。

我尝试了一下,发现并不会隐藏,一样可以顺利调用父类方法。

class Mammal {
 private:
  string name;
 public:
  Mammal(string n): name(n) {}
  virtual void speak() const {
   cout << "can't say anything from empty" << endl;
  }
  virtual void speak(const string st) const {
   cout << "can't say anything from string input" << endl;
  }
};

class Human : public Mammal{
 private:
  string job;
 public:
  Human(string n, string j): Mammal(n), job(j) {}
  virtual void speak(const string st) const {
   cout << "i'm human" << endl;
  }
};

int main() {
 Mammal *m = new Human("man", "spiderman");
 m->speak();
 return 0;
}

到此这篇关于EC++虚函数注意事项的文章就介绍到这了,更多相关EC++虚函数内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++虚函数注意事项

本文链接: https://www.lsjlt.com/news/161629.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++虚函数注意事项
    目录一、虚函数注意事项1.构造函数2.析构函数3.友元4.没有重新定义5.重新定义将隐藏方法文章转自公众号:Coder梁(ID:Coder_LT) 一、虚函数注意事项 在之前的文章当...
    99+
    2022-11-12
  • C++构造函数的一些注意事项总结
    目录1、匿名对象2、拷贝构造函数的调用时机3、深拷贝和浅拷贝总结1、匿名对象 首先应该明确匿名对象,匿名对象是之没有对象名,调用完构造函数后即析构的对象。下面通过代码捕捉类的构造函数...
    99+
    2022-11-12
  • 实现C++虚函数时的注意事宜有哪些
    实现C++虚函数时的注意事宜有哪些,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。C++中的C++虚函数的作用主要是实现了多态的机制,虚函数(Virtual Function...
    99+
    2023-06-17
  • python编写函数注意事项总结
    1、编写注意 (1)给函数指定描述名。 (2)函数名称只包括小写字母和下划线。 (3)每一个函数都应该包含简要说明其功能的注释,注释应该紧跟在函数定义之后,并且采用文档字符串格式。 ...
    99+
    2022-11-12
  • c语言函数的递归调用要注意哪些事项
    在C语言中,递归调用函数时需要注意以下几个事项:1. 递归的终止条件:递归函数需要定义一个终止条件,当满足这个条件时,递归调用将停止...
    99+
    2023-09-22
    c语言
  • python析构函数用法及注意事项
    主动删除对象调用del 对象;程序运行结束后,python也会自动进行删除其他的对象。 class Animal: def __del__(self): print("销毁对象{0}".f...
    99+
    2022-06-02
    python 析构函数
  • Golang函数的可变函数参数使用注意事项
    Golang是一种强类型、静态编程语言,其函数设计灵活,其中可变函数参数也是常见的实现方式之一,通常会用于函数参数个数不确定或者需要动态参数传递的场景。可变函数参数的使用虽然方便有效,但是也存在一些需要注意的问题,本文将详细介绍一下可变函数...
    99+
    2023-05-17
    Golang 注意事项 可变函数参数
  • C++函数模板非类型参数的注意事项有哪些呢
    本篇文章为大家展示了C++函数模板非类型参数的注意事项有哪些呢,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。C++编程语言中的模板应用是一个非常重要的应用技术。那么今天我们就先来了解一下有关C++函...
    99+
    2023-06-17
  • C/C++中的静态变量注意事项
    前言 C/C++中的静态变量,相信大多数人都用过,但你很可能用错了,包括你现在所在的项目中都可能埋着这个坑,不信我们往下看! 正文 我们先来看一段大家常写的代码,很简单,这段代码没啥...
    99+
    2022-11-13
  • c/c++语言位域注意事项分析
    复制代码 代码如下:struct weiyu{    int a:1;    int b:2;}a存放在内存的低位,在小端...
    99+
    2022-11-15
    c语言 位域
  • python编写函数的注意事项有哪些
    这篇文章将为大家详细讲解有关python编写函数的注意事项有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、编写注意(1)给函数指定描述名。(2)函数名称只包括小写字母和下划线。(3)每一个函数都应...
    99+
    2023-06-14
  • C/C++浮点数使用的两个注意事项详解
    目录一.回顾浮点数的存储与读取二.浮点数使用的第一个注意事项三.浮点数使用的第二个注意事项 附: 观察内存中的FLT_MAX和FLT_MIN补充:C 语言两个浮点数比较大小...
    99+
    2023-02-06
    c++ 浮点数 c语言正确的浮点数 c++浮点型
  • PHP函数的参数传递方式和注意事项
    PHP作为一种十分常用的后端代码语言,其函数的参数传递方式也是开发过程中需要注意的一部分。本文将探讨PHP函数的参数传递方式及其注意事项。PHP函数的参数传递方式在PHP中,函数的参数传递方式主要有三种:值传递、引用传递和默认值传递。下面分...
    99+
    2023-05-18
    注意事项 PHP函数 参数传递方式
  • C++继承的定义与注意事项
    目录一、什么是继承?1.1、概念1.2、定义1.2.1、继承关系和访问限定符1.2.2、继承基类成员访问方式的变化二、基类和派生类对象赋值转换三、继承中的作用域四、派生类的默认成员函...
    99+
    2022-11-12
  • java递归函数使用要注意哪些事项
    在使用Java递归函数时,需要注意以下几个事项:1. 基准条件:递归函数必须有一个终止条件,即基准条件。否则,递归函数将无限循环下去...
    99+
    2023-08-29
    java
  • 买虚拟主机要注意哪些事项
    买虚拟主机要注意:1、虚拟主机的稳定性,稳定性好有利于网站的收录;2、了解虚拟主机的功能支持,看是否能满足自身网站的需求;3、虚拟主...
    99+
    2023-02-14
    买虚拟主机 虚拟主机
  • Python开发注意事项:处理数据时的注意事项和技巧
    Python开发是一项广泛应用的编程任务,无论是数据分析、机器学习、Web开发还是其他领域,都可以借助Python来完成。在处理数据时,有一些注意事项和技巧,可以帮助开发者更高效地完成任务和避免潜在的问题。本文将介绍一些Python开发中处...
    99+
    2023-11-22
    数据处理技巧: 数据转换 数据处理技巧: 数据分析
  • C++中vector容器的注意事项总结
    目录容量(capacity)和大小(size)的区别容器扩容的本质emplace_back()和push_back()的区别emplace()和insert()的区别附:如果vect...
    99+
    2022-11-12
  • C#中HttpClient使用注意事项有哪些
    小编给大家分享一下C#中HttpClient使用注意事项有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!最近在测试一个第三方API,准备集成在我们的网站应用中...
    99+
    2023-06-29
  • 如何解析学习C++时注意事项
    如何解析学习C++时注意事项,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。许多编程人员学习C++总结经验为,有的觉得C++语言是一门独立的语言,并不是在C语言的基础上,可以直接...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作