2,继承、内联函数、虚继承、友元、构造析构函数、初始化列表
继承
- 2.1结构体成员权限
- 2.1.1访问权限
- 2.1.2类与结构体
- 2.2类的成员函数
- 2.2.1类内规则
- 2.2.2类成员内联函数inline
- 2.3类的继承
- 2.3.1类的继承与成员函数
- 2.3.2类的多继承
- 2.3.2.1类的多继承:菱形问题提出
- 2.3.3类的虚继承(关键字virtual)
- 2.4友元
- 2.4.1友元类
- 2.4.2友元函数
- 2.5构造函数和析构函数
- 2.6初始化列表
2.1结构体成员权限
2.1.1访问权限
访问权限有三种:
public 公共权限(类内可以访问,类外可以访问)
protected 保护权限(类内可以访问,类外不可以访问)(子类可以访问父类中的保护内容)
private 私有权限(类内可以访问,类外不可以访问)(子类不可以访问父类中的私有内容)
注意:protected 和 private 的设计是为了继承
2.1.2类与结构体
类:
类在游戏开发中用的最多
如果没有在类中显式定义构造函数和析构函数并指定访问权限,则默认情况下它们的权限都是公有的(public)
结构体:
结构体一般用于储存变量或数据
结构体也有构造(初始化)和析构(释放内存等),不写编译器就会默认生成,在游戏中对对象的生命周期的操作
#include<iostream>
using namespace std;
struct Test01
{
public:int a;void test01() {}
protected:int b;void test02() {}
private:float c;void test03() {}
};
class Test02
{
public:int d;void test04() {}
protected:int e;void test05() {}
private:float f;void test06() {}
};
int main()
{Test01 A;A.a = 10;int num1 = A.a;A.test01();//A.c;//因为设置了保护权限,所以不可以访问//A.test03();//因为设置了私有权限,所以不可以访问Test02 B;B.d = 20;int num2 = B.d;B.test04();//B.e;//因为设置了保护权限,所以不可以访问//B.test06();//因为设置了私有权限,所以不可以访问system("pause");return 0;
}
2.2类的成员函数
2.2.1类内规则
类内可以写静态函数、成员函数
静态函数不可以调用成员函数,成员函数可以调用静态函数
静态函数内不可以包含类内的成员信息(如果想调用需要使成员信息也变为静态)
全局的调用方式::
#include<iostream>
using namespace std;
int Fun1()
{return 1;
}class Test01
{
public:Test01();~Test01();static int a;static int b;static int Fun1()//类内可以添加静态函数{return a+b; //无法直接调用int a;和int b;需要转换为static形式}int Fun2()//类内可以添加成员函数{Test01::Fun1();//成员函数可以调用静态函数return 3;}
};
int Test01::a = 0;
int Test01::b = 0;
Test01::Test01()
{int num1 = ::Fun1();//::调用全局范围中的cout << num1 << endl;
}
Test01::~Test01()
{}struct Test02
{
public:static void Fun1();
};void Test02::Fun1() {}
int main()
{Test01 A;//实例化Test01::Fun1();A.Fun1();A.Fun2();Test02::Fun1();system("pause");return 0;
}
2.2.2类成员内联函数inline
为什么inline的效率会高效,因为编译时编译器会把代码副本放在每个调用函数的地方
可以使用在类成员内,也可以使用在全局中,也可以使用在结构体内
将简短的、频繁调用的函数声明为内联函数可以获得较好的效果。但是,对于复杂的函数或者在循环中调用的函数,使用内联可能导致代码膨胀,反而会影响性能如for、switch、递归等。
ue4中的FORCEINLINE也代表着内敛的效果,使用FORCEINLINE使需要包含头文件“CoreMinimal.h”
#include<iostream>
using namespace std;
class Test01
{
public://想要获取私有成员,不想私有成员被赋值可以用inline//比下面注释中的代码高效很多inline int Geta()const{return a;}/*int Geta()const{return a;}*/
private:int a;
};inline int Getb()
{return 0;
}struct Test02
{
public:inline int Getc()const{return c;}
private:int c;
};int main()
{Test01 A;A.Geta();Getb();Test02 C;C.Getc();system("pause");return 0;
}
2.3类的继承
2.3.1类的继承与成员函数
父类也成为基类,子类也称为派生类
封装SDK(插件)时只需要封装基类,其他人使用时只需要继承即可使用其中的方法,或者去扩展
游戏开发时大部分用的都是公共继承
//public
// public public
// protected protected
// private private
//provected
// public protected
// protected protected
// private private
//private
// public private
// protected private
// private private
2.3.2类的多继承
使用场景:如下列代码,将每一个系统部分封装到各个模块中,需要使用时直接调用即可,非常方便
可以将对象转换成某个模块
不需要直接转换成类,可以直接调接口,三个指针指向不同的继承接口,所以可以直接通过指针

#include<iostream>
using namespace std;
class UObject
{};class AActor :public UObject//只管和对象有关的
{
public:void Start() {}void End() {}void Net() {}
};class IPhysics//只管物理
{
public:void Simulate() {}
};class IAttack//攻击接口
{
public:void AttackTarget(ACharacter* InTarget) {}
};class ACharacter :public AActor,public IPhysics,public IAttack
{};bool IsSimulate(IPhysics* p)//好处是不需要直接转换成类,可以直接调接口
{if (p){p->Simulate();}return true;
}
int main()
{ACharacter A;//多继承ACharacter B;A.Start();A.End();A.Simulate();A.AttackTarget(&B);//A为多继承的,继承了IPhysics、IAttack、AActorIPhysics* p = &A;
//因为A继承了IPhysics接口(通过ACharacter类的多继承),
//A对象可以被视为一个IPhysics对象
//将A对象的地址赋值给指针p,就可以通过指针p来访问A对象的IPhysics接口IAttack* p1 = &A;AActor* p2 = &A;IsSimulate(&A);system("pause");return 0;
}
2.3.2.1类的多继承:菱形问题提出
A的类型为ACharacter,同时继承了AActor和UHello,而AActor和UHello同时继承了UObject,用A调用UObject时会出现二义性,不知道调用的是AActor的UObject还是UHello的UObject
A.Destroy();调用的是UHello的还是AActor的?
这既是菱形问题,要避免
解决菱形问题需要用到虚函数,在下文会解决
#include<iostream>
using namespace std;
class UObject
{
public:void Destroy() {}
};class AActor :public UObject//只管和对象有关的
{
public:void Start() {}void End() {}void Net() {}
};class UHello :public UObject
{};class IPhysics//只管物理
{
public:void Simulate() {}
};class ACharacter;//因为class ACharacter在后面,所以先声明,也可以在IAttak内部使用前加class
class IAttack//攻击接口
{
public:void AttackTarget(class ACharacter* InTarget) {}
};class ACharacter :public AActor,public IPhysics,public IAttack,public UHello
{};bool IsSimulate(IPhysics* p)//好处是不需要直接转换成类,可以直接调接口
{if (p){p->Simulate();}return true;
}
int main()
{ACharacter A;IPhysics* p = &A;IAttack* p1 = &A;AActor* p2 = &A;IsSimulate(&A);//A.Destroy();//会报错,类型不明确//调用的是UHello的还是AActor的system("pause");return 0;
}
2.3.3类的虚继承(关键字virtual)
虚继承使class B和class C继承的public A变成一个共享的类,因此class D只用调用一次A
尽量避免虚继承问题
#include<iostream>
using namespace std;
class A
{
public:A(){printf("A\n");}void Hello(){printf("Hello\n");}
};
class B :virtual public A
{
public:B() :A() {}
};
class C :virtual public A
{
public:C() :A() {}
};
class D :public B, public C
{
public:D()//c保错,编译器不知道构造B还是C{}~D() {}
};
int main()
{D d;d;//没虚继承前输出结果为A输出了两次//A//Ad.Hello();//正常情况下会报错,在class B和C的继承public A前加上virtual变为虚继承//输出结果为//A//Hellosystem("pause");return 0;
}
2.4友元
2.4.1友元类
使用友元可以访问另一个类内的所有内容
#include<iostream>
using namespace std;
class FTestClass
{friend class FTest2;//友元
public:void Hello() {}
private:void Hello1() {}void Hello2() {}void Hello3() {}
protected:void Hello4() {}
};class FTest2
{
public:void Init(){Class.Hello();Class.Hello1();//因为是private权限,正常会报错,使用友元不会报错Class.Hello4();//因为是protected权限,正常会报错,使用友元不会报错}
private:FTestClass Class;
};int main()
{FTest2 Test2;Test2.Init();system("pause");return 0;
}
2.4.2友元函数
友元不能被继承
优点:提高了程序的运行效率
缺点:破坏了类的封装以及稳点性
友元关系本身不具备继承性
#include<iostream>
using namespace std;
class FTest1
{
public:friend void Printf_f(FTest1 &T){T.Hello();printf("%d\n", T.a);printf("%d\n", T.b);}void Printf_a(){printf("%d\n", a);printf("%d\n", b);printf("%d\n", c);}int c = 100;static void Printf_b(FTest1& T){T.Hello();printf("%d\n", T.a);printf("%d\n", T.b);}
private:void Hello(){a = 0;//其实是this->a=0;编译器省略了b = 10;}
private:int a;int b;
};int main()
{FTest1 A;Printf_f(A);A.Printf_a();FTest1::Printf_b(A);//静态函数system("pause");return 0;
}
2.5构造函数和析构函数
#include<iostream>
using namespace std;
class FTest1
{
public:};class FTestA
{
public:FTestA();FTestA(int ina, int inb, int inc);~FTestA();
public:int a;int b;int c;FTest1* T;
};FTestA::FTestA()
{a = 1;b = 2;c = 3;
}FTestA::FTestA(int ina, int inb, int inc)
{a = ina;b = inb;c = inc;T = new FTest1();//分配内存
}FTestA::~FTestA()
{if (T){delete T;T = nullptr;//将指针类型的变量 T 初始化为空指针}
}int main()
{FTestA A;//会走FTestA::FTestA()cout << A.a << " " << A.b << " " << A.c << endl;FTestA B(10,20,30);//会走FTestA(int ina, int inb, int inc);cout << B.a << " " << B.b << " " << B.c << endl;system("pause");return 0;
}
2.6初始化列表
初始化列表的语法是在构造函数的参数列表后使用冒号 “:”,接着是多个初始化器,每个初始化器由成员变量名和对应的初始值用逗号分隔。
有父类时父类排在最前面
一定要按照变量声明的顺序排列
初始化列表的优点:
初始化非静态常量成员变量:对于非静态常量成员变量,它们只能在初始化列表中进行赋值,不能在构造函数中赋值。
初始化引用成员变量:引用成员变量必须在构造函数中进行初始化,并且只能使用初始化列表进行初始化。
初始化基类成员变量:如果派生类包含一个基类,那么初始化列表可以用于调用基类的构造函数,并初始化基类成员变量。
性能优化:使用初始化列表可以避免先创建再赋值的过程,提高效率。
注意:
初始化列表只能在构造函数中使用
初始化顺序固定
初始化列表只能在编译时确定初始值,无法在运行时根据条件或变量的值来决定初始值。
初始化列表中的初始化操作无法直接处理异常或错误。
#include<iostream>
using namespace std;
class FTest1
{
public:};class FHello_F{};class FTestA:public FHello_F
{
public:FTestA();FTestA(int ina, int inb, int inc);~FTestA();
public:int a;int b;int c;FTest1* T;
};FTestA::FTestA()
{a = 1;b = 2;c = 3;
}FTestA::FTestA(int ina, int inb, int inc)
//初始化列表:FHello_F()//有父类时放在最前面,a(ina)//一定要按照变量声明的顺序排列,b(inb),c(inc)
{T = new FTest1();//分配内存
}FTestA::~FTestA()
{if (T){delete T;T = nullptr;}
}int main()
{FTestA A;//会走FTestA::FTestA()cout << A.a << " " << A.b << " " << A.c << endl;FTestA B(10,20,30);//会走FTestA(int ina, int inb, int inc);cout << B.a << " " << B.b << " " << B.c << endl;system("pause");return 0;
}
相关文章:
2,继承、内联函数、虚继承、友元、构造析构函数、初始化列表
继承 2.1结构体成员权限2.1.1访问权限2.1.2类与结构体 2.2类的成员函数2.2.1类内规则2.2.2类成员内联函数inline 2.3类的继承2.3.1类的继承与成员函数2.3.2类的多继承2.3.2.1类的多继承:菱形问题提出 2.3.3类的虚继承(关键字virtual) 2.4友元…...
Mkdocs中利用Js实现大小圈鼠标拖动样式
在docs/javascripts/extra.js下复制粘贴: var CURSOR;Math.lerp (a, b, n) > (1 - n) * a n * b;const getStyle (el, attr) > {try {return window.getComputedStyle? window.getComputedStyle(el)[attr]: el.currentStyle[attr];} catch (e) {}return …...
pytorch(6)——神经网络基本骨架nn.module的使用
1 神经网络框架 1.1 Module类的使用 NN (Neural network): 神经网络 Containers: 容器 Convolution Layers: 卷积层 Pooling layers: 池化层 Padding Layers: 填充层 Non-linear Activations (weighted sum, nonlinearity): 非线性激活 Non-linear Activations (other): 非线…...
论文精读之BERT
目录 1.摘要(Abstract) 2.引言(Introduction): 3.结论(Conlusion): 4.BERT模型算法: 5.总结 1.摘要(Abstract) 与别的文章的区别是什么:BERT是用来设计去…...
实战:Docker+Jenkins+Gitee构建CICD流水线
文章目录 前言Jenkins部署创建Jenkins docker-compose配置maven源启动Jenkins容器安装插件Gitee ssh公匙配置与测试项目提交 Jenkins创建流水线写在最后 前言 持续集成和持续交付一直是当下流行的开发运维方式,CICD省去了大量的运维时间,也能够提高开发…...
7.25 Qt
制作一个登陆界面 login.pro文件 QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on …...
P1420 最长连号
题目描述 输入长度为 n n n 的一个正整数序列,要求输出序列中最长连号的长度。 连号指在序列中,从小到大的连续自然数。 输入格式 第一行,一个整数 n n n。 第二行, n n n 个整数 a i a_i ai,之间用空格隔开…...
UVA-1354 天平难题 题解答案代码 算法竞赛入门经典第二版
GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 这道题需要: 1. 遍历二叉树的每种构成方式。我这里每次把当前所有结点列出,然后遍历选取两个组合构成一个新结点,原来的结点剔除,新结点加入。…...
电机故障诊断(python程序,模型为CNN结合LSTM)
代码运行环境要求:TensorFlow版本>2.4.0,python版本>3.6.0 运行效果视频:电机故障诊断(python代码)_哔哩哔哩_bilibili 1.电机常见的故障类型有以下几种: 轴承故障:轴承是电机运转时最容…...
ubuntu 20.04 rtc时间显示问题探究
1、硬件与软件 本次测试的硬件为RK3568芯片,操作系统为ubuntu 20.04。 2、RTC与系统时间 先说结果,如果RTC驱动不可用或者RTC内部存储的时间非法, 那么操作系统会存储上一次有效的时间,当再次上电时,date命令会使用存储…...
数值分析第七章节 用Python实现非线性方程与方程组的数值解法
参考书籍:数值分析 第五版 李庆杨 王能超 易大义编 第7章 非线性方程与方程组的数值解法 文章声明:如有发现错误,欢迎批评指正 文章目录 迭代法求解 x e x − 1 0 xe^x-10 xex−10牛顿法求解 x e x − 1 0 xe^x-10 xex−10简化牛顿法求解 …...
利用MATLAB制作DEM山体阴影
在地理绘图中,我们使用的DEM数据添加山体阴影使得绘制的图件显得更加的美观。 GIS中使用ArcGIS软件就可以达到这一目的,或者使用GMT,同样可以得到山体阴影的效果。 本文提供了一个MATLAB的函数,可以得到山体阴影。 clear all;c…...
ubuntu 使用 rsync 的 SSH 方式同步备份远程WEB服务器
ubuntu 20.04 自带 rsync ,对于 WEB 服务器这种更新频率不高的情况,直接使用定时同步复制远程服务器的方法,比较直接和简单! $ rsync --version rsync version 3.1.3 protocol version 31 参考: Ubuntu20.04中的rsyn…...
机器学习 | Python实现NARX模型预测控制
机器学习 | Python实现NARX模型预测控制 目录 机器学习 | Python实现NARX模型预测控制效果一览基本介绍研究内容程序设计参考资料效果一览 基本介绍 机器学习 | Python实现NARX模型预测控制 研究内容 贝叶斯黑盒模型预测控制,基于具有外源输入的非线性自回归模型的预期自由能最…...
M5ATOMS3基础03给ROS1发一个问候(rosserial)
引出问题 关于之前2020年的博客: 01. ESP8266和ROS调试一些问题汇总 02. ESP8266和ESP32配置(需使用ROS1和ROS2) 效果展示 使用M5ATOMS3与ROS1(kinetic,melodic,noetic)版本通信比较通用的是…...
基于Vue3实现鼠标按下某个元素进行移动,实时改变左侧或右侧元素的宽度,以及点击收起或展开的功能
其原理主要是利用JavaScript中的鼠标事件来控制CSS样式。大致就是监听某个DOM元素的鼠标按下事件,以及按下之后的移动事件和松开事件。在鼠标按下且移动过程中,可实时获得鼠标的X轴坐标的值,通过简单计算,可计算出目标元素的宽度&…...
使用MyBatis(2)
目录 一、定义接口、实体类、创建XML文件实现接口) 二、MyBatis的增删改查 🍅1、MyBatis传递参数查询 🎈写法一 🎈写法二 🎈两种方式的区别 🍅2、删除操作 🍅3、根据id修改用户名 &#x…...
【FPGA/D6】
2023年7月25日 VGA控制器 视频23notecodetb 条件编译error时序图保存与读取??RGBTFT显示屏 视频24PPI未分配的引脚或电平的解决方法 VGA控制器 视频23 note MCU单片机 VGA显示实时采集图像 行消隐/行同步/场同步/场消隐 CRT:阴极射线管 640…...
【WebGIS实例】(10)Cesium开场效果(场景、相机旋转,自定义图片底图)
效果 漫游效果视频: 【WebGIS实例】(10)Cesium开场效果(场景、相机 点击鼠标后将停止旋转并正常加载影像底图: 代码 可以直接看代码,注释写得应该比较清楚了: /** Date: 2023-07-28 16:21…...
【Spring】IOC的原理
一、 IOC 的概念 Spring 的 IOC ,即控制反转,所谓控制反转 —— 本来管理业务对象(bean)的操作是由我们程序员去做的,但是有了 Spring 核心容器后,这些 Bean 对象的创建和管理交给我们Spring容器去做了&am…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...
一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...
Linux操作系统共享Windows操作系统的文件
目录 一、共享文件 二、挂载 一、共享文件 点击虚拟机选项-设置 点击选项,设置文件夹共享为总是启用,点击添加,可添加需要共享的文件夹 查询是否共享成功 ls /mnt/hgfs 如果显示Download(这是我共享的文件夹)&…...
