根据C 中的变量值创建成员函数
Create member function according to variable value in C++
原始代码太复杂了,所以我抽象出以下问题:
class A {
public:
A (int p): _p{p} {}
float computeA (float a) {
if (_p == 0)
return 0.1f + expf(a);
else if (_p == 1)
return 0.2f + sqrtf(a);
else if (_p == 2)
return 0.3f + sinf(a);
return 0.4f +cosf(a);
}
float accumulate() {
...
for(...) {
int temp = computeA();
// other calculations...
}
...
}
...
private:
const int _p;
};
_p 是 a 中的常数成员,只能是0、1、2或3。strong>取决于 _p 的值。由于在创建 a 时已经知道 _P ,因此我想知道是否有适当的方法可以避免代码中的" IF"条件。
仅更改每个子类的一行代码( a ),多态性不实用(或它是?)strong>有所作为)。另一个问题可能是性能,因为简单的 computea()经常以重 comgumulate()的大回路调用。多态函数调用的开销会变得不可接受吗?
谢谢,
您可以使用简单的功能指针:
float compute0(float a) { return 0.1f + expf(a); }
float compute1(float a) { return 0.2f + sqrtf(a); }
float compute2(float a) { return 0.3f + sinf(a); }
float compute3(float a) { return 0.4f + cosf(a); }
class A {
public:
typedef float (*functype)(float);
A (int p) {
switch (p) {
case 0: _func = &compute0; break;
case 1: _func = &compute1; break;
case 2: _func = &compute2; break;
default: _func = &compute3; break;
}
float computeA (float a) {
return _func(a);
}
...
private:
functype _func;
};
或,如果您想喜欢它,则可以使用lambdas:
class A {
public:
A (int p) {
switch (p) {
case 0: _func = [](float a) { return 0.1f + std::exp(a); }; break;
case 1: _func = [](float a) { return 0.2f + std::sqrt(a); }; break;
case 2: _func = [](float a) { return 0.3f + std::sin(a); }; break;
default: _func = [](float a) { return 0.4f + std::cos(a); }; break;
}
float computeA (float a) {
return _func(a);
}
...
private:
std::function<float(float)> _func;
};
另外,让创建A
对象的代码决定要计算的值和功能:
class A {
public:
typedef float (*functype)(float);
A (float value, functype func) :
_value(value), _func(func)
}
float computeA (float a) {
return _value + _func(a);
}
...
private:
const float _value;
const functype _func;
};
A a1(0.1f, &expf);
A a2(0.2f, &sqrtf);
A a3(0.3f, &sinf);
A a4(0.4f, &cosf);
或:
class A {
public:
using functype = std::function<float(float)>;
A (float value, functype func) :
_value(value), _func(func)
}
float computeA (float a) {
return _value + _func(a);
}
...
private:
const float _value;
const functype _func;
};
A a1(0.1f, std::exp);
A a2(0.2f, std::sqrt);
A a3(0.3f, std::sin);
A a4(0.4f, std::cos);
或使用多态性,让呼叫者决定要使用哪个子类(甚至创建自己的子类以进行自定义计算):
class A {
public:
A () {}
virtual float computeA (float a) = 0;
...
};
class A_exp : public A {
public:
float computeA (float a) override { return 0.1f + std::exp(a); }
};
class A_sqrt : public A {
public:
float computeA (float a) override { return 0.2f + std::sqrt(a); }
};
class A_sin : public A {
public:
float computeA (float a) override { return 0.3f + std::sin(a); }
};
class A_cos : public A {
public:
float computeA (float a) override { return 0.4f + std::cos(a); }
};
A_exp a1;
A_sqrt a2;
A_sin a3;
A_cos a4;
多态性不实用(或它是?),仅更改每个子类的一行代码...
确定是。基本类型具有所有相同的代码,除了computeA()
,它变为纯虚拟的:
float computeA(float) = 0;
然后,每个基础仅覆盖该方法。
请注意,如果间接函数调用开销是可以接受的(请参见以下部分),那么您可以让构造函数取一个std::function<float(float)>
,然后让呼叫者通过expf
,sqrtf
等通过,等等。这样,您就不需要子课,并且类消费者不仅限于四个功能 - 它们也不仅限于仅限功能(函数变得可行)。
多态函数调用的开销会变得不可接受吗?
这是一个很好的问题,您应该通过对两个选项进行基准测试。
如果您坚持有条件的方法,请提出一些建议:
-
_p
应该更恰当地是class enum
类型,以使您没有魔术数字在代码中流动。 - 考虑使用
switch
代替if
。由于通常以计算机为goto实现,因此它具有更快的速度。(但是,智能编译器可能会将您的多条条件优化为单个计算机。)
相关文章:
- C++-我可以创建另一个类的成员并在构造函数中使用它吗
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 使用成员在类中创建 lambda 表达式
- 使用带有 ref 参数的成员函数创建线程时出现编译错误
- C++ 双向链表:使用矩阵类成员创建和填充列表
- C++:将向量传递到构造函数以创建成员变量的最佳方法?
- 从类指针的向量创建成员变量的向量
- 根据模板参数条件 C++17 创建成员别名
- 为原始指针、智能指针和值创建成员函数的编译时变体
- C :如何声明std ::函数而无需创建成员函数以分配给它们
- VS2017 非标准语法。使用 ' &' 创建成员指针
- 根据C 中的变量值创建成员函数
- 在C++中创建成员函数模板专用化
- 如果成员对象是父类的一部分,则无法创建成员对象
- 如何通过元编程正确创建成员模板函数指针数组
- 需要帮助创建c++成员函数来表示任务与RTOS microcos III
- 在可变模板函数中创建成员函数指针元组
- 如何在实例和静态作用域之间创建成员变量
- 将使用typedef创建成员吗?
- 内部类——c++,内部类,以及为什么你只能创建成员作为指向它们的指针