现代c++中的内联方法和代码可读性
inline methods and code readability in modern C++
好吧,有时候我的"编码大脑"会跳过一个档位;偶尔你能听到齿轮的摩擦声。(例如,每隔一段时间我就会写class Foo : Bar {}
,然后提醒自己这已经不合适了——而且已经很长时间了)。
我目前的习惯是在不牺牲速度的情况下使用内联方法来提高代码的可读性和可维护性,但是我最近遇到了一个问题,这使我对这种做法产生了质疑。
因此,给定(无可否认是人为的)代码,如: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)上开发的,并希望保持它"跨平台安全"。
解决这个小问题的办法是让他们脱离现实;但是,这会影响我的表现吗?考虑到涉及深奥的数学,可读性是一个严肃的问题;但它仍然必须表现良好。
更新:
澄清一下,使用更多/不同的——和更做作的——代码:
#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?");
}
这段代码在两个平台的Static中都可以正常工作;它将在Linux上作为共享库工作。当尝试将其用作DLL时,它将在Windows下给出错误。唯一的解决方法是将CheckValue
方法移出。
"老派"inline
将CheckValue
方法的代码"按原样"替换为调用它的地方;显然,"新派"内联确实……没有什么?(因为编译器显然不顾一切地做它想做的事。)
AFIK使此工作在DLL下的唯一方法是将CheckValue
移出行…对于时间敏感的"老派"代码(每次调用都是/被保证的函数开销)来说,这可能是一个问题。这仍然是个问题吗?是否有"更好"的方法来保持可读性;例如,不要假设为我编写代码的每个CS/CE都精通统计学?
注意:这是跨平台的,所以"编译器"可能不是一个有意义的短语。
您想使用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);
如果您的问题是确保性能,最好的处理方法是插入一个assert()
来执行完整性检查。
应该由调用者来确保正确的值传递给你的概率函数(并且应该有很好的文档记录),如果一些调用者不这样做,assert()
将帮助你调试。然而,当您发布代码时,您可以简单地停用所有断言,从而消除检查的性能损失。
没有什么比根本不检查更快的了,这就是为什么C/c++中的解引用指针从来都不是安全的,也永远不会是安全的。
不知道你的问题是什么,但是这个呢:
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();
};
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 如何重写全局方法名称以在调用原始方法之前将我的代码推到前面
- 在nodejs中使用本机代码的最佳方法是什么?
- 函数从唯一代码调用正确的子类方法
- 如何启用使用另一个类的静态方法的模板函数的自动推导,从而消除冗长的调用方代码
- 有没有更好的方法来编写这个c++代码
- 终端进程终止,退出代码为:1有什么方法可以修复它吗
- 有没有一种预处理器的方法可以从调试符号中删除代码段
- C++:销毁此代码的最佳方法是什么?
- 在.cpp文件中定义方法而不是在 C++ 的 .h 文件中定义方法时,如何提高代码的性能?
- 为什么在我的代码中没有调用 g 模拟方法
- 设计许多单例代码结构的更好方法
- 两种专用方法中的相同代码
- Android 无法从本机代码调用 Java 方法 JNI
- 我的类中有方法的指针数组,但我不能调用我的方法.代码如下
- 如何在子类中获得相同的方法代码而不重复代码
- 如何只执行一次方法代码,尽管每帧调用一次
- 模板化的方法代码在哪里分配?