/**
* 行继续操作符【\】:表示用符号\,连接的内容,都是定义同一个宏的内容
* #:表示将参数字符串化
* ##:表示连接内容
* 宏定义里有用'#'或'##'的地方宏参数不会展开,需要转换宏,进行展开
* inline:c++的关键字
* __inline: c和c++都可以用,功能与inline一致
* __forceinline:c和c++都可以用,不基于编译器的性能和优化分析而依赖于程序员的判断进行内联,
但它也不保证 一定内敛,有些情况函数是肯定不能内敛的
* 使用宏的好处:可以精简写法,易于复用;如:本例的方法可以快速定义类属性的set和get方法
* 使用宏的坏处:
1.在编写宏时,报错始终在使用宏的位置
2.报错不能确提示,对于发现错误不友好
3.不能对宏逻辑进行断点调试
*/
#define GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName,PropertyName) \
static std::string Get##PropertyName##Attribute() \
{ \
return #PropertyName; \
}
#define GAMEPLAYATTRIBUTE_VALUE_GETTER(ClassType,PropertyName) \
__inline ClassType Get##PropertyName() \
{ \
return PropertyName; \
}
#define GAMEPLAYATTRIBUTE_VALUE_SETTER(ClassType,PropertyName) \
__forceinline void Set##PropertyName(ClassType NewVal) \
{ \
PropertyName = NewVal; \
}
// Uses macros from AttributeSet.h
#define ATTRIBUTE_ACCESSORS(ClassName,ClassType,PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName,PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(ClassType,PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(ClassType,PropertyName)
class MyClass
{
private:
float Health;
public:
MyClass();
~MyClass();
ATTRIBUTE_ACCESSORS(MyClass,float,Health)
};
MyClass::MyClass()
{
Health = 20;
}
MyClass::~MyClass()
{
}
//#define A (2)
//#define STR(s) #s
//#define CONS(a,b) int(a##e##b)
//
#define A 2
#define _STR(s) #s
#define STR(s) _STR(s)/** 转换宏 [9/3/2020 ZC] */
#define _CONS(a,b) (int)a##e##b
#define CONS(a,b) _CONS(a,b)/** 转换宏 [9/3/2020 ZC] */
//
#define ANY_PACKAGE ((MyClass*)-1)
int main()
{
/** INT_MAX没有被展开 [9/3/2020 ZC] */
printf("int max:%s\n",STR(INT_MAX));
/** 不进行转换,编译错误,A没被展开 [9/3/2020 ZC] */
/** 转换后,编译正确 [9/3/2020 ZC] */
printf("CONS(a,b)=>%d\n",CONS(A,A));
MyClass Temp;
std::cout << MyClass::GetHealthAttribute() << std::endl;
std::cout << Temp.GetHealth() << std::endl;
Temp.SetHealth(100);
std::cout << Temp.GetHealth() << std::endl;
}
UE4中对c/c++宏用法分析
最新推荐文章于 2024-02-01 10:29:11 发布