IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> UE4蓝图函数的参数传递问题 -> 正文阅读

[C++知识库]UE4蓝图函数的参数传递问题

我们知道,在原生的C++编程中,函数在进行值传递的时候,其实是利用了外部的一个值变量,调用class的拷贝构造函数,创建了一个临时变量,如下一段代码

struct A
{
	int i = 0;
	A()
	{
		cout << "A constructor" << endl;
	}
	A(const A& Other)
	{
		cout << "A copy constructor" << endl;
	}
	A& operator=(const A& Other)
	{
		cout << "A operator" << endl;
        return *this;
	}
};

void PrintStruct(A& a)
{
	a.i = 1;
}
void PrintStruct2(A a)
{
	a.i = 1;
}
int main()
{
	A a;
	PrintStruct(a);
	PrintStruct2(a);
	return 0;
}

输出为

第一行的输出为a的构造输出,这正常,PrintStruct因为是引用传递,所以没有构造新的变量,没有输出,PrintStruct2因为是值传递,所以用a作为参数,调用了A的拷贝构造函数生成了一个临时变量给函数使用。

稍微熟悉UE4蓝图的同学都知道,在UE4的蓝图函数中,既可以使用值传递,也可以使用引用传递,那么它的运行方式是不是和原生C++一样呢?经过我的测试,并不一样。

为了测试这个问题,我们新建一个UE4工程后,添加如下测试结构体

USTRUCT(BlueprintType)
struct FTestStruct
{
	GENERATED_USTRUCT_BODY()
	UPROPERTY(BlueprintReadWrite, EditAnyWhere)
		int value1;
public:
	FTestStruct();
	FTestStruct(const FTestStruct& Other);
	FTestStruct& operator = (const FTestStruct& Other);
};
FTestStruct::FTestStruct()
{
	value1 = 3;
	GameLog(Log, TEXT("FTestStruct constructor. value1 = %d"), value1);
}

FTestStruct::FTestStruct(const FTestStruct& Other)
{
	value1 = Other.value1;
	GameLog(Log, TEXT("FTestStruct copy constructor. value1 = %d"), value1);
}

FTestStruct& FTestStruct::operator = (const FTestStruct& Other)
{
	value1 = Other.value1;
	GameLog(Log, TEXT("FTestStruct operator. value1 = %d"), value1);
	return *this;
}

可以看出,我们为FTestStruct添加了构造函数、拷贝构造函数、赋值操作符,并且在对应的函数中打印了输出。

打开编辑器后,我们在一个Actor蓝图中添加结构体变量MemTestStruct,设置value=10,并添加函数PrintStruct(FTestStruct),即函数的参数为值传递。GamePlay中调用PrintStruct,如下图

?在这个断点之后,看到输出为

FTestStruct constructor. value1 = 3
FTestStruct operator. value1 = 10

这说明了什么呢?从这个现象看,蓝图函数的值传递做法和C++原生的函数值传递做法不一样,蓝图函数是先构造了一个临时变量,所以先有构造函数的输出,然后用外部的值向临时变量赋值,于是便调用了class的赋值函数,就有了operator的输出,并不是原生C++一次性的拷贝构造。

当我把值传递改成引用传递后,便没有了输出,说明引用传递确实如其名,没有临时的对象生成。

在测试这个问题的过程中,我还发现了一个额外的有趣的现象,那就是我给Actor加了一个MemTestStruct变量并设置value=10之后,什么也不做(不添加PrintStruct这种测试函数),运行游戏,Actor生成的时候会有如下输出

FTestStruct constructor. value1 = 3
FTestStruct operator. value1 = 10

这个现象这么解释?现在我还没深入研究底层代码,但从这个现象来看,第一行的构造输出是Actor本身生成时候的Struct构造输出。关于第二行输出的解释,我们知道,编辑Actor之后,其实Actor本身是作为一种资产保存在磁盘上的,那么value=10其实也是被保存在了磁盘中,之后加载的时候,用这块数据向向MemTestStruct赋值,便有了operator的输出。由此可知,Actor里面的结构体,其实在运行游戏的时候有两个过程,一个是本身构造,另一个是赋值操作。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-25 21:31:04  更:2021-07-25 21:31:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 6:27:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码