好吧,有时我的编码大脑"跳过一个装备;偶尔你会听到齿轮磨损。 (例如,我每隔一段时间写一次class Foo : Bar {}
,然后再提醒自己“不再适合 - 并且还没有长时间。” / p>
我目前的MO是使用内联方法来提高代码的易读性和可维护性而不牺牲速度,但我最近遇到了一个问题让我对这种做法提出质疑。
所以,给出(公认的设计)代码,如:
double a;
double b = 0.0;
double c = 0.0;
...
// do some stuff here
...
// skip the sanity checks
// Magic Formula. This does what?
a = b + c - (b * c);
...
我会写:
double a;
double b = 0.0;
double c = 0.0;
...
// do some stuff here
...
// skip the sanity checks
// Oh! It's probability!
a = ProbabilisticOr(b, c);
...
inline double ProbabilisticOr(double b, double c)
{
// Skip the Sanity checks
return b + c - (b * c);
}
我现在正在进行的数学计算相当复杂。如果我想要一个通用的CS / CE能够维护它,它必须写得更像第二个。代码对时间非常敏感。
正如我上面所说,我最近碰到了一个问题。我让我的数学常数static const double ...
像个好程序员一样;但是当试图内联访问它们时,编译器会弹出DLL。目标操作系统是Linux,但是我在Windows上开发(Visual Studio 2013)并且希望保持它"跨平台安全"。
解决这个小问题is to take them out-of-line;但是,这会伤害我的表现吗?鉴于所涉及的深奥数学,可读性是一个严重的问题;但它仍然必须表现良好。
更新
澄清,使用更多/不同 - 更加人为的 - 代码:
#ifndef BUILD_DLL
# define DLL_MODE __declspec(dllimport)
#else
# define DLL_MODE __declspec(dllexport)
#endif
class DLL_MODE ContrivedProbabilityExample
{
public:
inline ContrivedProbabilityExample(double value);
inline ContrivedProbabilityExample& operator+=(double value);
private:
inline void CheckValue(double value);
private:
static const double ZERO_PROB = 0.0;
static const double GUARANTEED_PROB= 1.0;
double probability;
private:
// Not implemented
ContrivedProbabilityExample();
};
inline ContrivedProbabilityExample::ContrivedProbabilityExample(double value) : probability(value)
{
CheckValue(value);
}
inline ContrivedProbabilityExample& ContrivedProbabilityExample::operator+=(double value)
{
CheckValue(value);
probability = probability + value - (probability * value);
}
inline void ContrivedProbabilityExample::CheckValue(double value)
{
if(value < ZERO_PROB || value > GUARANTEED_PROB)
throw std::range_error("Hey, whattaya think you're doing?");
}
这个代码在两个平台上都可以正常运行;它将作为Linux上的共享库。尝试将其用作DLL时,它会在Windows下出错。唯一的解决方案是将CheckValue
方法移出线外。
&#34;老派&#34; inline
已将CheckValue
方法的代码替换为&#34; as-is&#34;从哪里调来;显然&#34;新学校&#34;内联确实......什么都没有? (因为无论如何编译器显然都会做它想要的。)
AFIK在DLL下进行此项工作的唯一方法是将CheckValue
移出线外...这可能是时间敏感代码的问题&#34;老派&#34; (每次通话都是保证功能开销)。这还是个问题吗?是否有更好的&#34;保持这种可读性的方法;例如不要假设每个在我的代码上工作的CS / CE都会精通统计数据吗?
注意:这是跨平台的,所以&#34;编译器&#34;可能不是一个有意义的短语。
答案 0 :(得分:1)
您想使用constexp
,例如:
inline constexpr double ProbabilisticOr(double b, double c)
{
// Skip the Sanity checks
return b + c - (b * c);
}
然后你可以自由地做以下事情:
static const double a = ProbabilisticOr(b, c);
答案 1 :(得分:0)
不确定你的问题是什么,但是这个:
class DLL_MODE ContrivedProbabilityExample
{
public:
ContrivedProbabilityExample(double value)
{ CheckValue(value); }
ContrivedProbabilityExample& operator+=(double value)
{
CheckValue(value);
probability = probability + value - (probability * value);
}
private:
void CheckValue(double value)
{
if(value < ZERO_PROB || value > GUARANTEED_PROB)
throw std::range_error("Hey, whattaya think you're doing?");
}
private:
constexpr double ZERO_PROB = 0.0;
constexpr double GUARANTEED_PROB= 1.0;
double probability;
private:
// Not implemented
ContrivedProbabilityExample();
};
答案 2 :(得分:0)
如果您的问题是确保性能,处理此问题的最佳方法是插入assert()
以执行完整性检查。
应该由调用者确保将正确的值传递给您的概率函数(并且应该有详细记录),如果某些调用者没有,assert()
将帮助您调试。但是,当您发送代码时,您可以简单地停用所有断言,从而消除检查的性能损失。
没有什么比不检查更快,这就是为什么在C / C ++中解除引用指针永远不会安全,永远不会。