virtual关键字与多态

<C++>初识多态,剖析virtual关键字 熬过无人问津的日子,才有诗和远方✨写在前面 多态是C++面向对象三大特性之一函数重写和重载的比较 下面用具体代码讲解多态: 这里把Animal类设为父类,子类Dog和子类Cat都公共继承Animal父类。父类中的eat前加了virtual关键字,那么eat函数就被叫做虚函数,这些就满足了多态的条件。此外,doEat函数的参数列表是父类的引用,那么也就满足了多态使用的父类引用或指针指向子类对象。 如果doEat不加引用,那么运行结果就会是: vi 阅读详情

今天在网上看到这么一段博文(以下蓝色为引用):

一,  什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你就应该从这里开始)

简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的策略。下面来看一段简单的代码

class A{
public:
void print(){ cout<<”This is A”<<endl;}
};

class B:public A{
public:
void print(){ cout<<”This is B”<<endl;}
};

int main(){   //为了在以后便于区分,我这段main()代码叫做main1
A a;
B b;
a.print();
b.print();
}

通过class A和class B的print()这个接口,可以看出这两个class因个体的差异而采用了不同的策略,输出的结果也是我们预料中的,分别是This is A和This is B。但这是否真正做到了多态性呢?No,多态还有个关键之处就是一切用指向基类的指针或引用来操作对象。那现在就把main()处的代码改一改。

int main(){   //main2
A a;
B b;
A* p1=&a;
A* p2=&b;
p1->print();
p2->print();
}

运行一下看看结果,哟呵,蓦然回首,结果却是两个This is A。问题来了,p2明明指向的是class B的对象但却是调用的class A的print()函数,这不是我们所期望的结果,那么解决这个问题就需要用到虚函数

class A{
public:
virtual void print(){ cout<<”This is A”<<endl;}  //现在成了虚函数了
};

class B:public A{
public:
void print(){ cout<<”This is B”<<endl;}  //这里需要在前面加上关键字virtual吗?
};

毫无疑问,class A的成员函数print()已经成了虚函数,那么class B的print()成了虚函数了吗?回答是Yes,我们只需在把基类的成员函数设为virtual,其派生类的相应的函数也会自动变为虚函数。所以,class B的print()也成了虚函数。那么对于在派生类的相应函数前是否需要用virtual关键字修饰,那就是你自己的问题了。

现在重新运行main2的代码,这样输出的结果就是This is A和This is B了。
重点在main2中,没有virtual关键字,即使是用基类的指针指向派生类,也还是达不到多态的目的。这是之前没有注意到的,是这样吗?有待实际运行一下来验证。

【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法 C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法 阅读详情

相关推荐

langchain入门学习笔记

langchain快速入门

1734

虚函数

文章目录虚函数虚函数的定义虚函数使用的注意事项虚表什么是虚表图解说明虚表的四种情况一般继承(无虚函数覆盖)一般继承(有虚函数覆盖)多重继承(无虚函数覆盖)多重继承(由虚函数覆盖) 虚函数虚函数的定义 虚函数是一个类的成员函数,它的定义语法如下: 特别注意: 当一个类的一个成员函数被定义为虚函数时,则由该类派生出来的所有派生类中,该函数始终保持虚函数的特征 当在派生类中重新定义虚函数时,不必加关...

weixin_38607041的博客 1万+

【高清照片】深圳光博会看PCIe Over Fibre 实现方案

本文分析了PCIe over Fibre技术及其在数据中心的应用前景。该技术通过光纤延伸PCIe总线,解决了传统铜缆距离限制问题,支持跨机架资源池化。目前主要有两种实现方式:CDFP混合光缆方案和Retimer转接卡方案,各有优缺点。文章还探讨了CDFP接口的现状、低速信号传输解决方案,以及PCIe速率与光通信发展的对应关系。最后对比了PCIe光缆与以太网光缆的关键差异,指出PCIe光互连在协议透明度和边带信号处理上的特殊要求。随着标准推进,PCIe over Fibre将成为数据中心扩展高带宽、低时延互连

Saniffer的博客 1392

虚函数详细理解

在实现c++多态时会用到虚函数。虚函数使用的其核心目的是通过基类访问派生类定义的函数。所谓虚函数就是在基类定义一个未实现的函数名,为了提高程序的可读性,建议后代中虚函数都加上virtual关键字。一般格式:上述代码在基类中定义了一个test的虚函数,所有可以在其子类重新定义父类的做法这种行为成为覆盖(override),或者为重写。常见用法:声明基类指针,利用指针指向任意一个子类对象,调用相关的虚函数,动态绑定,由于编写代码时不能确定被调用的是基类函数还是那个派生类函数,所以被称为“”虚“”函数。

chen_ever的博客 2442

Ubuntu 22.04 局域网安装GitLab

下面直接给你一份。

u013250861的博客 669

【学习笔记-QGIS】 QGIS从零快速上手

安装文章参考:https://zhuanlan.zhihu.com/p/370633306。

Xcong_Zhu的博客 1万+

虚函数详解

一、什么是虚函数 类的成员函数前加 virtual 这种函数就叫做虚函数 二、和虚函数相关的一些概念 1、纯虚函数:在虚函数的声明的后面添加=0,这种虚函数就叫纯虚函数。可以不实现,但如果实现必须在类外(只能在父类的构造函数、析构函数中调用) 2、抽象类:成员函数中有纯虚函数,这种类叫抽象类,抽象类不能实例化(不能创建对象),抽象类必须被继承且纯虚函数被覆盖后,由子类实例化对象,如果继承抽象类,但...

程序员小明 8372

ADS 2023 实战:手把手教你仿真一个中心频率 2.4GHz 的带通滤波器(附工程文件)

本文详细介绍了使用ADS 2023软件设计和仿真中心频率2.4GHz带通滤波器的全流程,包括工程准备、指标定义、原理图设计、仿真优化及实际电路实现。通过切比雪夫滤波器拓扑和参数优化,实现高性能的带通滤波器设计,适用于无线通信系统。附有工程文件和常见问题解决方案,助力工程师快速掌握射频滤波器设计技巧。

weixin_30790841的博客 482

C++基础之虚函数

一.虚函数的定义 虚函数是指在基类中声明为virtual并在一个或多个派生类中被重定义的成员函数,即被virtual关键字修饰的成员函数。 具体格式为:virtual 返回值类型 函数名(参数表){函数体}。 注意:我们知道,在同一个类中不能定义两个名字相同、参数个数和类型都相同的函数,否则就是“重复定义”,但是在类的继承层次结构中,在不同的层次中可以出现名字相同、参数个数和类型都相同而功能不同的函数。 二.虚函数的作用 C++中的虚函数的作用主要是实现了多态的机制。简而言之就是用父类型别的指针指向其子

baidu_41191295的博客 3141

Mstar的Monitor方案OSD 菜单制作(五)——icon绘制

Mstar的Monitor方案(五)————绘制icon

android 系统定制开发那些事 1807

coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?

🏆本文收录于《优快云问答解惑-专业版》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!

**My Coding Family** 2670

虚函数的定义、用法以及纯虚函数和虚析构函数

虚函数是一种成员函数,它允许子类重写(override)父类中定义的函数。 虚函数的重要意义便是实现多态性。 多态性是面向对象编程的一个核心概念:即同一个接口可以有不同的实现,从而实现代码的灵活性和通用性。虚函数的关键字为virtual。用virtual关键字来声明一个函数为虚函数。声明一个虚函数的目的是允许派生类重写该函数,以提供特定的实现,而通过基类的指针或引用调用虚函数时,将根据对象的实际类型来调用相应的函数实现。

shaohua_du的博客 2391

人形机器人电源系统硬件开发:从原理图设计到PCB布局的完整流程

人形机器人是“移动的智能终端”,其电源系统如同“心脏+血管”:既要为大脑(主控)、肌肉(电机)、感官(传感器)提供稳定能量,又要在有限体积内应对高动态负载(如跳跃时电机瞬间大电流)。本文聚焦“硬件开发”维度,覆盖从需求分析到PCB制板的完整流程,适合硬件工程师、机器人爱好者快速掌握工程实战方法。

AI天才研究院 2176

【学习笔记】virtual 关键字,虚函数与多态

就是一个函数在不同的场景下,表现出不同的状态(行为,特性等)。下面举两个例子,第一个例子比较偏生活。比如你是一家公司的 CEO,你手下有销售部,运营部,技术部三个部门,你对三个部门下达一个指令。

码的世界 4335

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

继承与多态 virtual关键字的使用场景

父类子类有同名函数时在外部调用时如果不加父类名则会默认调用子类的函数。C++有函数重写的功能需要添加virtual关键字,当时写上篇博文的时候在想那么既然默认使用子类的同名函数那么这个virtual有什么意义呢? 这篇博文主要讲述 多态:一句相同的语句能有不同的实现。      当父类和子类有同名函数,调用时牵扯到了指针那么就跟virtual有关系了。   看以下几种情况:   定义两个...

zzt4326的博客 341

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

【C++ 关键字 virtual 】C++ virtual 关键字(将成员函数声明为虚函数实现多态

在C++的早期设计中,通过基类指针可以访问派生类的成员变量,这是由于派生类对象在内存中的布局是基类成员变量在前,派生类成员变量在后。因此,当我们使用基类指针指向派生类对象时,可以正常访问到派生类中从基类继承来的成员变量。 然而,对于成员函数,情况就不同了。在编译时期,成员函数并不会被放入对象的内存空间中,而是存放在一块单独的内存区域,每个类只有一份成员函数的代码。当我们通过基类指针调用成员函数时,编译器会根据指针的静态类型(也就是基类类型)去查找对应的成员函数,而不是动态类型(也就是实际指向的派生类类型)

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 3098

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

CPlusPlus - #016 virtual关键字实现多态

virtual关键字实现多态

AlanL的专栏 360

C++多态特性:virtual关键字的使用

C++多态特性:virtual关键字的使用

欧特GO 627

【C++多态】 --- 多态问题抛出与virtual关键字

1. C++中多态的概念 C++中所谓的多态(polymorphism)是指,由继承而产生的相关的不同的类,其对象对同一消息会作出不同的响应。 2. C++多态问题抛出 下面看一个具体的例子: #include <iostream> #include <stdlib.h> using namespace std; class Animal { public: void speak(void) { cout << "动物在说话" << en

M2嵌入式 534

不使用virtual关键字实现C++多态

#include using namespace std; /* 不使用virtual实现多态可以用成员函数指针完成。 成员函数指针形式:返回类型(A::*指针名)(形参表) 其中A是类类型,即这个指针是指向A类的成员函数的函数指针 例如:int(A::*P)(int,int)这

iFuMI的博客 1359

c++多态——virtual关键字,C++11 override 和 final,析构函数的重写。

c++多态——virtual关键字,C++11 override 和 final,析构函数的重写。

zgwnb666的博客 1328

c++中virtual关键字的作用与Java中多态的一点对比

动机 最近一直在使用C++写win32程序,用了一些库,里面提供的类和demo各种是virtual这个关键字,一直不是很明白到底是啥用,于是查看了一些文档,写小程序来实验它的作用。 结论 virtual这个关键字的发挥作用是在子类去继承父类的时候。比如: class Person { public: void foo1() ...

weixin_33853827的博客 353

C++中的virtual与inline:实现多态与内联调用的关键字

详细介绍了C++中的两个重要关键字:virtual和inline。virtual用于实现多态,允许子类重新定义父类的方法;而inline用于内联函数,可以在调用点直接展开函数体,以提高程序的运行效率。

qq_35320456的博客 1183

C++ 学习笔记 (七)继承与多态 virtual关键字的使用场景

  在上一篇C++ 学习笔记 (六) 继承- 子类与父类有同名函数,变量中说了当父类子类有同名函数时在外部调用时如果不加父类名则会默认调用子类的函数。C++有函数重写的功能需要添加virtual关键字,当时写上篇博文的时候在想那么既然默认使用子类的同名函数那么这个virtual有什么意义呢? 这篇博文主要讲述 多态:一句相同的语句能有不同的实现。      当父类和子类有同名函...

argentina1111的博客 308

virtual关键字及多态的实现

virtual关键字

u010039733的专栏 478

virtual 是 C++ 中的一个关键字,用于实现多态性(polymorphism)

是 C++ 中的一个关键字,用于实现多态性(polymorphism)。它的主要作用是在基类中声明虚函数(virtual function),允许派生类重写这些函数,并在运行时根据对象的实际类型调用适当的函数版本。关键字使得 C++ 支持运行时多态性,这意味着在程序运行时,根据对象的实际类型选择合适的函数版本。这种机制广泛应用于面向对象编程,尤其是在需要处理一组相关对象时,通过基类指针或引用统一操作。

m0_46376834的博客 987
上一篇: 邮件收发协议相关
下一篇: http header详解
zhhx310
博客等级 码龄18年 2粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值