C++如何实现类似C#中的属性(Property)
2024-06-11
66
前言
在C#中,属性(Property)是比较常用的,也是非常有用的特性,通过属性,可以比较方便的在对类的一些成员变量赋值或取值的时候执行一些代码,以达到赋值或取值的时候做出特定的动作。而在C++中,类就只有成员变量和成员函数,没有类似C#中的属性的用法。
C++如何实现属性
定义属性类
C++可以通过自定义类的方式来实现类似属性的功能,先定义一个Property模板类,代码如下:
#include functional
templateclass T
class Property
{
std::functionT (void) _get;
std::functionvoid(const T) _set;
public:
Property(
std::functionT (void) get,
std::functionvoid(const T) set)
: _get(get),
_set(set)
{ }
Property(
std::functionT(void) get)
: _get(get),
_set([](const unsigned int){})
{ }
operator T () const { return _get(); }
void operator = (const T t) { _set(t); }
};
使用属性类
在Test类中使用以上定义的属性类来实现属性:
class Test
{
private:
std::string _label;
public:
Propertystd::string Label = Propertystd::string
(
[this]()-std::string
{
return this-_label;
},
[this](const std::string value)
{
this-_label = value;
}
);
Propertyunsigned int LabelSize = Propertyunsigned int
(
[this]()-unsigned int
{
return this-_label.size();
}
);
};
在Test类中,我们定义了Label和LabelSize两个Property类型的成员变量,其中Label初始化的构造函数,传入了get和set对应的lambda表达式作为get和set执行时执行的代码,LabelSize初始化的构造函数只包含了get执行的代码,是一个只读的属性。
测试代码如下:
Test test;
test.Label = std functional;
std::cout label = std::string(test.Label) std::endl
label size = int(test.LabelSize) std::endl;
在测试代码中,我们申明了一个Test类型的变量test,给Label赋值,可以直接像赋值字符串一样把一个常量或string类型的字符串赋值给它,而Label是只读属性,可以直接通过强制类型转换为int。同时,也可以直接谈LabelSize赋值给一个int的变量,并且不需要写强制类型转换的代码。以上测试代码的运行结果如下:
label = std functional
label size = 14
C++属性的优缺点
我们通过自定义一个Property类,然后通过lambda表达式的方式,实现类似C#中get和set时执行相应的代码,这种方式有优点也有缺点。
主要优点:
- 能实现类似C#的属性的功能
- 通过lambda表达式实现get和set的执行代码,使用简单
- 用法上也比较直观,可以直接转换为模板中的模板类型变量,也可以反过来转换
主要缺点:
- 不能完全像C#使用那么灵活
- 在表达式中如果没有明显的类型推导,需要写强制类型转换
- 如果模板类中是一个类,无法直接通过“.”或“-”访问到类的成员,需要先转换为对应类型的变量才能访问,这对于连续多级属性使用上不方便
总之,这也是一种习惯于C#的属性的用户来说,在C++中也是一种行之有效个替代方法,可以根据自己的程序代码的要求进行取舍,在C++中规范的做法还是用成员函数getXXXX和“setXXXX”来实现属性的访问。
更新于:5个月前赞一波!
相关文章
- 【说站】css旋转属性如何理解
- 【说站】python解释器如何实现字典合并
- 【说站】python逻辑值检测如何实现
- 【说站】java重复注解如何实现
- 【说站】python中__file__属性的使用
- 【说站】python thread模块如何实现多线程
- 【说站】java虚拟扩展方法如何实现
- 【说站】Java数组如何实现动态初始化
- 【说站】java中如何实现可重入的自旋锁
- 【说站】java动态代理如何实现?
- CSS font-family 属性设置字体
- 禁止添加属性、封闭对象、冻结对象的 API
- flex 弹性布局常用属性
- 初识: 对象的属性特征
- CSS 边框属性总结
- Vue2 计算属性 computed【初识】
- Vue 指令之v-bind指令绑定属性
- v-bind 绑定 class、style 属性
- 在Java中如何把两个对象相同属性赋值
- CSS布局:完全掌握position属性
文章评论
评论问答