c++ - 没有标准构造函数的类的 C++ 属性模板
问题描述
我想实现一个完全不使用 C 宏的 C# 属性的 C++ 等价物。get()
我创建了一个模板,它基本上以一种比set()
. 在构造函数中还有两个类型的参数std::function
,我可以在其中覆盖默认的 getter 和 setter 方法。
template<typename T>
class Property
{
public:
Property(T initialValue, std::function<void(T&)> setter, std::function<T&()> getter)
{
Value = initialValue;
Setter = setter;
Getter = getter;
}
~Property()
{
}
void operator =(T value)
{
if(Setter == nullptr)
{
Set(value);
}
else
{
Setter(value);
}
}
T& operator ()()
{
if(Getter == nullptr)
{
return Get();
}
else
{
return Getter();
}
}
void Set(T& value)
{
Value = value;
}
T& Get()
{
return Value;
}
private:
T Value;
std::function<void(T&)> Setter = nullptr;
std::function<T&()> Getter = nullptr;
}
以下代码片段显示了Property
类型对象的定义int
。(getter 和 setter 被 lambda 表达式覆盖。)
Property<int> prop = Property<int>(0,
[&](int& val)
{
// some code inside the overridden setter
prop.Set(val);
},
[&]() -> int&
{
// some code inside the overridden getter
return prop.Get();
});
Getter 和 setter 的调用方式如下:
int foo = prop();
prop = foo;
我以为一切都会好起来的,而且确实如此。在我尝试将一个不包含标准构造函数的类作为模板类型传递之前,它确实如此。我知道,声明T Value;
会导致问题,但我无法找出任何替代方案或解决方法。
也许,您知道如何在没有标准构造函数的情况下使这个概念适用于原始类型、类和类。
解决方案
IMO,这门课是个坏主意。
所有这些std::function
s 可能会增加合理的开销(在性能和内存方面)。
也就是说,这是答案:
未Value
在构造函数的成员初始化列表中指定默认初始化(然后分配值)的Property
原因。Value
解决方案是在成员初始化器列表中对其进行初始化,而不是在构造函数主体中分配给它:
Property(T initialValue, std::function<void(T&)> setter, std::function<T&()> getter)
: Value(initialValue)
{
Setter = setter;
Getter = getter;
}
Setter
为and做同样的事情是个好主意Getter
。
此外,Get
并且operator()
不得返回非const
引用(按值或按const
引用返回)。在此处返回非常量引用允许用户绕过指定的设置器并直接更改值。此外,您应该制作Get
和operator()
const
。
operator=
, Set
, 并且std::function<...> Setter
应该通过const
引用获取新值。
您应该将对的引用和对它的引用作为参数传递T Value
,Setter
而const
不是Getter
在 lambda 中捕获对属性的引用。如果引用被移动,捕获引用会使您的课程中断。
Getter
应该按值返回(以允许它返回修改后的Value
),或返回void
(如果它的唯一目的是在返回值时调用函数,而不能修改返回的内容)。
推荐阅读
- amazon-web-services - 仅当请求来自特定 VPC 时才允许代码构建操作
- javascript - 通过 react js (pwa) 中的 service worker 推送通知
- bitbucket-pipelines - 获取当前分支名称
- javascript - 我无法从下拉菜单中正确删除项目。它删除了多个
- javascript - 如何比较猫鼬模式中的密码?
- android - reactnative IllegalViewOperationException:无法对带有标签的视图执行操作dispatchViewManagerCommand:1909,因为视图不存在
- python - OAuth 功能不适用于 WHM cPanel
- python - pandas DataFrame中的移位值
- php - Laravel 删除重复查询并按名称排序
- java - 定时器不启动