原文链接:https://blog.csdn.net/qq_51470638/article/details/142151502
一、背景
在面向对象编程时,常常要添加类成员变量。
然而类成员一旦多了之后,也会带来干扰。
拿到一个类,一看成员变量好几十个,就问你怕不怕?
二、解决思路
可以借助函数式编程思想,来消除一些不必要的类成员变量。
三、实例
举个例子:
class ClassA{
public:
...
int funcA()
{
m_valueA += 10;
return m_valueA;
}
int funcB()
{
m_valueB += 100
return m_valueB;
}
private:
int m_valueA = 0;
int m_valueB = 0;
};
上面的类中,m_valueA
仅仅被funcA()
使用,m_valueB
仅仅被funcB()
使用,如果这些变量作为类成员:
- 对于那些不需要使用它们的方法而言,是一种干扰;
- 同时,也会让这些变量不那么可控,因为控制者无法保证其他方法不会修改它;
可以写成:
class ClassA {
public:
ClassA()
{
{
int valueA;
m_funcA = [=] () mutable -> int {
valueA += 10;
return valueA;
};
}
{
int valueB;
m_funcB = [=] () mutable -> int {
valueB += 100;
return valueB;
};
}
}
...
int funcA ()
{
return m_funcA();
}
int funcB ()
{
return m_funcB();
}
private:
std::function<int()> m_funcA = nullptr;
std::function<int()> m_funcB = nullptr;
};
这样,就把m_valueA
和m_valueB
消除了——通过将它们闭包到lambda表达式中,然后将这个lambda存起来重复使用。
需要注意的是
mutable
修饰符和=
值捕获。如果用引用捕获,栈变量会释放导致非法访存;如果不加mutable
就无法修改值捕获的变量。
当然,lambda的初始化时机也可以更改,例如放到使用时,同时也做了判空更加健壮:
class ClassA {
public:
int funC ()
{
printf ("hello world");
}
int funcA ()
{
if (!m_funcA) {
int valueA;
m_funcA = [=] () mutable -> int {
valueA += 10;
return valueA;
};
}
return m_funcA();
}
int funcB ()
{
if (!m_funcB) {
int valueB;
m_funcB = [=] () mutable -> int {
valueB += 100;
return valueB;
};
}
return m_funcB();
}
private:
std::function<int()> m_funcA = nullptr;
std::function<int()> m_funcB = nullptr;
};