知识屋:更实用的电脑技术知识网站
所在位置:首页 > 科技

【UE4】通俗易懂 用蓝图来学习 C++ 基础知识

发表时间:2022-03-25来源:网络

【前言】:

用老罗来学UE蓝图:

https://zhuanlan.zhihu.com/p/135297007​zhuanlan.zhihu.com

再开个脑洞,用蓝图来类比学习C++基础知识。

C++ 刚开始学,所以本篇知识点不是特别全有些地方也可能不是特别准,望谅解,以后会慢慢补上。如有错误麻烦大佬们指出,感激不尽。

【杂谈】:

另:多少菜鸟的噩梦啊。

dbe5b735e71ab79657d8ba36c838566a.png

之前就是这样学习的,从书上提取知识点笔记记了一大堆,想着把书从薄读到厚,再从厚读到薄。

c69dea6573169e8530ab25707acf46eb.png

结果发现屁用都没有,该写程序的时候啥都不会,琐碎的知识点实在太多了。

所以:

知行合一 ——实战啊,不要一上来就把一本书从头到尾看一遍。尤其是这种天书是用来查的,跟字典一样,不是用来看的抓住重点,像那些比较难理解的知识点,琐碎的知识点以后会随着实战慢慢会补充上。总分——视频(教程)转文章——把别人的长视频(中英文)转化为文章,复习随时打开,既方便,逻辑又清晰,还省流量。分总——文章转图片——把别人的多文章转化为思维导图,将零碎重要知识点总结成一个框架以消化吸收,代码细节先不要管,先理解它有什么作用,含义,实战上手练习时再细究这些细节。

【导图】:

c6f2c2c4391d2b316e588caa25f50e47.png

cbc38b8af3f075d6af2ba1022a50eea5.png

一、 C++ Intro

【1.1】C++的诞生

Bjarne Stroustrup (来跟我一起唱,杯啊你 死招死咒噗~)唵嘛呢叭咪吽

它是在大佬头发郁郁葱葱的时候于1979年设计开发的,最初命名为带类的C,1983年更名为C++。C艹(四声、谢谢合作)对C进一步扩充和完善,而且随着时间发展会有不同的标准。

下面为五代标准。

1998——C++982003——C++032011——C++112014——C++142017——C++17

你们这些大佬啊,再研究研究这就是你们以后的下场,标准发型!毫无回天之术 。

b30fa2183dc8612c9a675f52d7575c7e.png

【1.2】重要组成部分

核心语言——提供所有构建块,包括变量、数据类型、常量等C++ 标准库——提供大量函数,用于操作文件、字符串等等标准模板库(STL)——提供了大量的方法,用于操作数据结构等

【1.3】C++面向对象开发的四大特性

Encapsulation 封装——数据封装将实现细节与相关数据分离开,防止函数直接访问类类型的内部成员。Abstract 抽象——抽象类不能被用于实例化对象,只能够用作接口使用,接口描述了类的行为和功能,而不需要完成类的特定实现。(如动物抽象类不能实例化出猴子、老虎这样的对象)。Inherited 继承——BaseClass基类 & DerivedClass派生类,继承允许我们依据一个类来定义另一个类,这使得创建和维护一个应用程序变得更容易,也达到了重用代码功能和提高执行效率的效果。Polymorphic 多态——有了多态,我们可以有多个不同的类,都带有同一个名称,但具有不同实现的函数,甚至函数参数可以相同。虚函数是C++中用于实现多态的机制。核心理念就是通过基类访问派生类定义的函数。

8f2dd1d9022608569821a73af95f04b4.png

二、C++基本语法

【2.1】Class类 & Object对象

基类——class Shape ;(有宽高属性)
基类的对象—— Shape sha; (类只有一个,但是对象可以有很多个,如Shape sha1、Shape sha2)
派生类——class Rectangle : public Shape ;(继承自基类,新添加了计算面积函数,宽乘高就行了)
派生类的对象——Rectangle Rect;

【01】:Class类

对同一类对象的共同属性和行为进行概括,形成类。比如人类、动物类、植物类等。如常有的属性是 颜色、大小、高低、重量、年龄等。

【02】:Object对象

对象Object,它是类的实例,用来特定类,所以是对象,常常定义属性的值

#include using namespace std; class Box { public: double length; // 长度 double breadth; // 宽度 double height; // 高度 }; int main() { Box Box1; // 声明 Box1 object对象,类型class为 Box // box 1 对象详述 Box1.height = 5.0; Box1.length = 6.0; Box1.breadth = 7.0; // box 1 的体积 volume = Box1.height * Box1.length * Box1.breadth; cout // 调用第一个命名空间中的函数 func(); return 0;

524d0409617030420ba403e44ce558a8.png

三、 .h(Header) 头文件和. cpp(C Plus Plus)源文件

类和对象分别对应了属性和值,而头文件和源文件分别对应了声明和实现。

头文件.h相当于领导(header),对应阳,起主导作用。对员工发号施令(声明一个大饼),以及负责外部商贸工作(#include 借力,给团队拉活儿,保证团队活下去)。源文件 .cpp相当于员工 ,起配合作用。接收领导的指令,996 地边吃着大饼,边实现老板的要求。

3b814c6b1528f15c843efceefcda64bb.png

85c7a291f69d12a34a8d9f098387bde5.png

四、Class Access Modifier 类访问修饰符(public、private、protected)

作用——它防止函数直接访问类类型的内部成员断句——每个标记区域(如private:)在下一个标记区域(如 public:)开始之前或者在遇到类主体结束右括号( int main(){ } )之前都有效。

【4.1】Public 公有成员

公有成员在类的外部是可以Get 和 Set 的。

5887077bb15c47b3e3c7a9387d40c52e.png

【4.2】Protected 受保护成员

保护成员在派生类(子类)中是可以Get的。 对于蓝图事件图表中的变量来说,就是Variable下的Private,勾选后,子类中只能Get 变量值,而不能够Set 变量值。(Event Graph 中变量的Private其实就相当于C++的 Protected)

8e9e83285ef227664d39e703f9044254.png

【4.3】Private 私有成员

私有成员变量或函数在类的外部是不可以访问的,只能够被本类成员(类内)和友元函数Get 。 (C++ 成员和类的默认访问修饰符是private,而BP蓝图默认访问修饰符是public) 对蓝图函数变量来说,就是函数Function/构造脚本内的Local Variable,只能供函数内部使用。

42d64bd1e67560662807c05cfa213998.png 对材质来说,就是Constant,只供材质使用。而不是ScalarParameter可以在实例中(对象)调节参数。

a5f729ebc64bcf21a4e1e6ad04ad2a48.png

【4.4】不同的继承方法

注意继承用 : 冒号继承 /*public*/ class A{}; class B: public A{}; /*protected*/ class A{}; class B: protected A{}; /*private*/ class A{}; class B: private A{}; public:类内、类的对象;派生类、派生类对象 都可以访问protected: 类内、派生类内 可以访问;类的对象和派生类的对象 不可访问

对象不可以访问,意思就是把类拽到关卡中变成对象的时候,get 不了对象的变量。

c56c36357f8f02021dda9557ffefc8a1.png private: 只有类内部可以访问;类的对象、派生类、派生类的对象,统统不可访问。(就上面【4.3】列举过的,一样)

526c96da3c3ffca2ce19c9315c39e7db.png

五、Variable 变量

【5.1】基础变量类型

int—— 整数,不带小数,占4byte(32bit)空间的整数,最大值为2的31次方-1float——浮点型,带小数double——双精度浮点值,占8byte(64bit)空间的整数,最大值为2的63次方-1char——占1byte的字符,取值范围为-128~127或0~255void——无类型/空类型/不输入返回任何值bool——true false

09a489a5391d3452cfdab3bf8a1d4460.png

【5.2】其他变量类型

【1】Constant常量

说明——常量是固定值,在程序执行期间不会改变,且定义后不能进行修改。两种声明方式 #define 预处理器 —— #define LENGTH 10 const 关键字—— const int LENGTH=10; 注意—— 分号断句、=等号、变量类型 这三点的区别安全检查——const 常量具有类型,编辑器可以进行安全检查,#define宏定义没有数据类型,只是简单的字符串替换,不能进行安全检查

【2】Array数组

说明——它用来存储一系列数据,但往往被认为是一系列相同类型的变量声明——int a[5]; 声明5个类型为int的数字访问单个数组元素——int b=a[0]——通过索引访问数组的第一个元素(index=0)

【3】Enum枚举

说明——它是由用户定义的若干枚举常量的集合声明—— enum color{red,green=5,blue}; ——索引从0开始,red值为0,green值为5,blue值为6enum color{red,green,blue}c; c=blue;—— 变量类型为color的c,然后c被复制为三个颜色中的一个blue蓝色

【4】String字符串

说明——字符串声明——char str[n]="xxxxxxxx"; 其他—— strcpy(a,b)—— 把b的字符串复制给astrcat(a,b)—— 连接a b 字符串

【5.3】typedef

为已有类型取一个新名字,如用int声明整数换成用a声明整数

typedef int a; a shit= 0 ;

【5.4】变量作用域

local variable——局部变量——在函数或代码块内部声明的变量——如 int main(){}主函数 { } 括号内声明的变量(上面提到过了,对应蓝图BP 函数Local Variables)global variable——全局变量——所有函数外部声明的变量——如 int main(){} 主函数前面声明的变量(非函数中定义的变量,如Event Graph中定义的全局变量)形式参数——在函数参数的定义中声明的变量——如 int func (int a);

b43499a8581c55b027acdb7a120b3103.png 形式参数

【5.5】存储类

存储类定义C++程序变量/函数的范围(Visibility)和生命周期(lifetime)

【1】Static

作用——static 修饰局部变量可以在函数调用之间保持局部变量的值,而不需要在每次它进入和离开作用域时进行创建和销毁

【2】Extern

作用——extren 存储类用于提供一个全局变量的引用。全局变量对所有程序文件都是可见的,当使用extren时,对于无法初始化的变量,会把变量名指向一个之前定义过的存储位置

01894f70e94c6889a233c32897cd3e4e.png

95774a15d20eac01d84fb7d2c70f13cb.png

六、Statement 语句

没啥说的了,看老罗BP吧。相关的循环语句条件语句蓝图版在老罗那篇。

【6.1】循环语句

whilefordo while嵌套循环breakcontinuegoto

【6.2】条件语句

ifif elseif 嵌套switchswitch嵌套

868555c38d95fffc87b59738bdea04ca.png

七、Pointers 指针

【7.1】指针

定义——指针是一个变量,其值为另一个变量的地址。每一个变量都有一个内存位置,每一个内存位置都定义了可使用& 连字号 运算符访问的地址,它表示了在内存中的一个地址符号—— 访问地址符号——&——它可以输出变量在内存中的地址声明指针符号——*——用来声明一个指针储存地址值注意事项—— 所有指针的值的实际数据类型(int、float、char等等)都一样,都代表了内存地址的长的16进制数*ip=n——带星号输出变量值ip=&n=0x0000001——不带星号输出地址值 int a; //&a表示地址 cout return 0; }

【8.2】constructor 构造函数

类似Construction Script构造脚本。

https://zhuanlan.zhihu.com/p/134279765​zhuanlan.zhihu.com 定义——类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行注意—— 构造函数的名称与类的名称是必须完全相同的并不会返回任何类型,也不会返回void作用—— 构造函数可用于为某些成员变量设置初始值主要用来创建对象时初始化对象,即为对象成员变量赋初始值格式—— // 不带参数 class A { public: A(); // 声明构造函数 }; A::A(void){}; //定义构造函数 //带参数 class A { public: A(int len); // 声明构造函数 }; A::A(int len){}; //定义构造函数 使用初始化列表来初始化字段 C::C(int a,int b,int c):X(a),Y(b),Z(c){} //等同于 C::C(int a,int b,int c) { X=a; Y=b; Z=c; }

【8.3】deconstructor 析构函数

定义——在每次删除所创建的对象时执行注意——析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号 ~ 作为前缀作用——析构函数有助于在跳出程序(如关闭文件、释放内存等)前释放资源格式—— class A{ public: A(); //声明构造函数 ~A(); //声明析构函数 A::A(void){}; //定义构造函数 A::~A(void){}; //定义析构函数

【8.4】copy constructor 拷贝构造函数

定义——它在创建对象时,是使用同一类中之前创建的对象类初始化新创建的对象作用—— 它在创建对象时,是使用同一类中之前创建的对象类初始化新创建的对象。复制对象把它作为参数传递给函数复制对象,并从函数返回这个对象格式—— classname(const classname &obj){} //其中 obj是一个对象引用 A(const A &obj);

【8.5】friend 友元函数

定义——类的友元函数是定义在类外部,有权访问类的所有私有(private)和保护(protected)成员注意——尽管友元函数的原型有在类的定义中出现过,但是友元函数不是类成员函数格式—— class Box{ public: friend void print(Box box); //定义友元函数 }; void print(Box box){}; //声明友元函数 int main(){ Box box; box.变量=n;// 访问对象中的变量 print(box); }

【8.6】inline 内联函数 (默认就是内联的)

定义——如果一个函数是内联的,那么编译时编译器会把该函数的代码副本位置放在每个调用该函数的地方注意—— 在类定义中的定义的函数都是内联函数,即使没有inline说明符内联函数一般都是1~5行的小函数内联函数中不允许使用loop循环和switch开关语句内联函数的定义必须出现在内联函数第一次调用之前作用—— 编译时把函数的定义替换到调用的位置解决程序中函数调用的效率问题

【8.7】virtual void 虚函数

【1】虚函数

为什么虚——并不能确定被调用的是基类的函数还是派生类的函数,所以被成为”虚“函数哪儿虚?——虚在推迟联编或动态联编上,一个类函数的调用并不是在编译时刻确定的,而是在运行时刻被确定的定义——虚函数是在 基类中使用 关键字 virtual声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态连接到该函数作用——定义为虚函数是为了允许 用基类的指针来调用子类的这个函数注意—— 定义一个函数为虚函数,不代表函数为不被实现的函数定义一个函数为纯虚函数,才代表函数没有被实现

【2】纯虚函数

定义——纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法作用——定义纯虚函数是为了实现一个接口,起到一个规范的作用通俗——健林口袋里的一个小目标对自己来说不算啥,但是要求任何思聪都要有自己的花法,是正经地投资?还是花天酒地泡妞。每个思聪都有自己的花法,健林不闻不问。格式—— virtual void func()=0
收藏
  • 人气文章
  • 最新文章
  • 下载排行榜
  • 热门排行榜