![在这里插入图片描述](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* 指针的转换。