UE4CPP String转换与C++转换

    ![在这里插入图片描述](https://img-blog.csdnimg.cn/7fd748317d4540c5bdd4144e99eb02cf.png)

String转换
做一个小球上下移动

void ABall::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	FString Mystring = FString::SanitizeFloat(DeltaTime);

	FVector NewLocation = GetActorLocation();

	float DeltaHeight = (FMath::Sin(RuningTime + DeltaTime)-FMath::Sin(RuningTime));

	FString SDeltaHeight = FString::SanitizeFloat(DeltaHeight);

	NewLocation.Z += DeltaHeight * 200.f;

	RuningTime += DeltaTime;

	SetActorLocation(NewLocation);
	Print_T(SDeltaHeight);
}

void ABall::Print_T(FString SDeltaHeight)
{
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(-1, 8.0f, FColor::Green, SDeltaHeight);
	}


}

附MSB3073 代码为6(解决),没写实现
不允许使用不完整类型(解决),项目属性,输出目录改为父级

一个旋转的医疗包


```cpp
// Fill out your copyright notice in the Description page of Project Settings.


#include "TestActor.h"

// Sets default values
ATestActor::ATestActor()
{
	StopLooping = true;

 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	HeathMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticmesh"));
	Root_C = CreateDefaultSubobject<USceneComponent>(TEXT("HelloWorld"));
	RootComponent = Root_C;
	HeathMesh->AttachToComponent(Root_C, FAttachmentTransformRules::KeepRelativeTransform);
}

// Called when the game starts or when spawned
void ATestActor::BeginPlay()
{
	Super::BeginPlay();
	TurnAndTurn();
}

// Called every frame
void ATestActor::Tick(float DeltaTime)
{ 
	Super::Tick(DeltaTime);

}

void ATestActor::TurnAndTurn()
{
	  if (MyHandle.IsValid())
	  {
		  GetWorldTimerManager().ClearTimer(MyHandle);
	  }
	  if (StopLooping)
	  {
		  //获得旋转
		  FRotator MyRotation = HeathMesh->GetComponentRotation();
		  //弧度
		  float Down = FMath::RandRange(0.1f,0.05f);	//120/360=0.27;
		  //角度
		  float N = 57.4;//180/3.14
		  MyRotation.Yaw += Down * N;
		  HeathMesh->SetWorldRotation(MyRotation);
	  }
	  GetWorldTimerManager().SetTimer(MyHandle, this, &ATestActor::TurnAndTurn, 0.03f, true);
}

UFUNCTION,

Ufunction( 函数说明符, Category=“Lif68|Test”, meta = (元数据说明符) )

BlueprintImplementableEvent:在C++可以声明函数(不能定义,蓝图重写),在C++里调用该函数,蓝图重写实现该函数
BlueprintNativeEvent:在C++可以声明和定义函数,在C++里调用该函数,蓝图重写实现该函数(蓝图可以重写或不重写C++父类函数)

而*BlueprintImplementableEvent函数内部也不能带参,会报错
在这里插入图片描述在这里插入图片描述

而NativeEvent在C++中不执行(未被蓝图调用过的情况下执行)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

纯函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
另一种:

UFUNCTION(BlueprintPure, meta=(DisplayName = “HelloWorld”, CompactNodeTitle = “Hello”, Keywords = Hello, CommutativeAssociativeBinaryOperator = “true”), Category = “Hello”)
float MyFloat(float A, float B);
在这里插入图片描述

其中:
Displayname为HelloWorld
我们既可以用Helloworld找到,也可以用MyFloat找到,且其显示名为HelloWorld
KeyWords=”Set Of Kwywords”
指定搜索此函数时可以使用的一组关键字,例如,当放置节点以调用蓝图图形中的函数时
在这里插入图片描述
在这里插入图片描述

而CompactNodeTitle = “Hello”
在这里插入图片描述
而CommutativeAssociativeBinaryOperator = "true"则是添加针脚
在这里插入图片描述
而Category
在这里插入图片描述
制作一个Make节点
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

制作一个Enum暴露到蓝图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

reinterpret_cast

reinterpret_cast 是 C++ 中的一种类型转换运算符,主要用于将指针或引用转换为其他类型的指针或引用。它允许将任意类型的指针或引用转换为其他类型的指针或引用。
但也是一种危险的类型转换,通常用于需要在底层内存层面进行类型转换的特殊情况。

reinterpret_cast<new_type>(expression)

其中,new_type 是目标类型,expression 是要转换的表达式。

将指针类型转换为其他指针类型

int a = 10;
void* p = &a;
int* ip = reinterpret_cast<int*>(p);

将指针类型转换为整数类型

int a = 10;
int* p = &a;
uintptr_t ip = reinterpret_cast<uintptr_t>(p); // uintptr_t 是定义在 <cstdint> 中的无符号整数类型,可以存储指针值

将整数类型转换为指针类型

uintptr_t ip = 0x12345678;
int* p = reinterpret_cast<int*>(ip);

将一个类的指针转换为一个无关的类的指针

class A { /*...*/ };
class B { /*...*/ };
A* a = new A();
B* b = reinterpret_cast<B*>(a);

注意事项
避免在常规代码中使用:reinterpret_cast 可能破坏类型系统的安全性,通常应该避免在常规代码中使用。
类型兼容性:使用 reinterpret_cast 时,应确保转换后的指针类型与原始指针类型在内存布局上是兼容的,否则可能会导致未定义行为。
使用场景:适用于一些需要底层类型转换的特殊场景,比如与硬件交互、实现底层数据结构、序列化/反序列化等。
总的来说,reinterpret_cast 是一种强大但危险的工具,应谨慎使用。

DynamicCast

dynamic转换既可以转为派生类,也可以转换为父类,当转换失败时,其会返回一个NULL指针,主要用于在继承层次结构中安全地进行类型转换。
dynamic_cast 只适用于有多态(polymorphism)关系的类,即必须包含至少一个虚函数。

用法

dynamic_cast<new_type>(expression)

其中,new_type 是目标类型,expression 是要转换的表达式。

将基类指针转换为派生类指针

Base* base = new Derived();
Derived* derived = dynamic_cast<Derived*>(base);

将基类引用转换为派生类引用

Base& baseRef = *base;
try {
    Derived& derivedRef = dynamic_cast<Derived&>(baseRef);
} catch (std::bad_cast& e) {
    std::cerr << "Bad cast: " << e.what() << std::endl;
}

StaticCast

static_cast 是 C++ 中的一种类型转换运算符,用于在编译时执行明确的类型转换。它是一种较为安全的转换方式,与传统的 C 风格转换((type)value)相比,static_cast 具有更强的类型检查能力,虽然安全性不如dynamiccast,但它无需virtual也可以使用。

基本语法

static_cast<new_type>(expression)

new_type 是要转换到的目标类型。
expression 是要转换的表达式。

基本数据类型之间的转换

int main() {
    int i = 42;
    double d = static_cast<double>(i); // 将整数转换为双精度浮点数
    std::cout << "d = " << d << std::endl;
    return 0;
}

指针和引用之间的转换

int main() {
    int i = 42;
    void* p = &i; // 将 int 指针转换为 void 指针
    int* ip = static_cast<int*>(p); // 将 void 指针转换回 int 指针
    std::cout << "*ip = " << *ip << std::endl;
    return 0;
}

类层次结构中的转换
在类层次结构中,static_cast 可以用于在基类和派生类之间进行转换(向上转换和向下转换),但在进行向下转换时,程序员需要确保这种转换是安全的。

class Base {
public:
    virtual ~Base() = default;
};

class Derived : public Base {
public:
    void sayHello() {
        std::cout << "Hello from Derived!" << std::endl;
    }
};

int main() {
    Base* b = new Derived(); // 基类指针指向派生类对象
    Derived* d = static_cast<Derived*>(b); // 向下转换
    d->sayHello();
    delete b;
    return 0;
}

重新解释常量性
static_cast 不能移除 const、volatile 或 __unaligned 限定符,但可以添加这些限定符。

int main() {
    const int ci = 42;
    int i = static_cast<int>(ci); // 添加 const 限定符
    std::cout << "i = " << i << std::endl;
    return 0;
}

使用注意事项

static_cast 进行的转换必须在编译时可确定,即转换必须是类型安全的。
进行向下转换时需要确保类型的正确性,否则可能会产生未定义行为。
不能用于动态类型检查,如果需要进行类型安全的向下转换,应使用 dynamic_cast。

何时使用 static_cast

在基本数据类型之间进行转换,如 int 到 double。
在相关类型的指针或引用之间进行转换。
在类层次结构中进行已知安全的向上或向下转换。
进行与 void* 指针的转换。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值