假设我正在编写一个 API,我的一个函数采用一个代表 channel 的参数,并且只会在值 0 和 15 之间。我可以这样写:
void Func(unsigned char channel)
{
if(channel < 0 || channel > 15)
{ // throw some exception }
// do something
}
或者我是否利用 C++ 作为一种强类型语言,让自己成为一种类型:
class CChannel
{
public:
CChannel(unsigned char value) : m_Value(value)
{
if(channel < 0 || channel > 15)
{ // throw some exception }
}
operator unsigned char() { return m_Value; }
private:
unsigned char m_Value;
}
我的功能现在变成了:
void Func(const CChannel &channel)
{
// No input checking required
// do something
}
但这完全是矫枉过正吗?我喜欢 self 记录和保证它是它所说的那样,但是值得为这样一个对象的构造和销毁付出代价,更不用说所有额外的打字了吗?请让我知道您的意见和替代方案。
最佳答案
如果您想要这种更简单的方法,请将其泛化,以便您可以从中获得更多用途,而不是针对特定事物进行定制。那么问题不是“我应该为这个特定的东西制作一个全新的类(class)吗?”但是“我应该使用我的公用事业吗?”;后者总是是的。实用程序总是很有帮助。
所以做这样的事情:
template <typename T>
void check_range(const T& pX, const T& pMin, const T& pMax)
{
if (pX < pMin || pX > pMax)
throw std::out_of_range("check_range failed"); // or something else
}
现在您已经有了这个用于检查范围的好工具。您的代码,即使没有 channel 类型,也可以通过使用它变得更简洁。你可以走得更远:
template <typename T, T Min, T Max>
class ranged_value
{
public:
typedef T value_type;
static const value_type minimum = Min;
static const value_type maximum = Max;
ranged_value(const value_type& pValue = value_type()) :
mValue(pValue)
{
check_range(mValue, minimum, maximum);
}
const value_type& value(void) const
{
return mValue;
}
// arguably dangerous
operator const value_type&(void) const
{
return mValue;
}
private:
value_type mValue;
};
现在你有了一个不错的实用程序,并且可以这样做:
typedef ranged_value<unsigned char, 0, 15> channel;
void foo(const channel& pChannel);
而且它可以在其他场景中重复使用。只需将其全部粘贴到 "checked_ranges.hpp"
文件中,并在需要时使用它。进行抽象从来都不是坏事,而且拥有实用程序也无害。
另外,永远不要担心开销。创建一个类只需运行您无论如何都会执行的相同代码。此外,干净的代码比其他任何东西都更受欢迎;性能是最后一个问题。完成后,您可以使用分析器来测量(而不是猜测)慢速部分的位置。
关于c++ - 强类型语言能走多远?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3181766/