UE4蓝图函数的参数传递问题

23 篇文章 12 订阅

我们知道,在原生的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里面的结构体,其实在运行游戏的时候有两个过程,一个是本身构造,另一个是赋值操作。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值