c++ - 强类型语言能走多远?

标签 c++ api types strong-typing

假设我正在编写一个 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/

相关文章:

postgresql - 如何在 PostgreSQL (9.1) 函数中将字符转换为整数?

c++ - QT qmake 指令中定义?

c++ - IntelliSense:无法打开包含路径中的源文件

javascript - 我想一键调用两个函数,并确保它们将一个接一个地工作

java - 使用 Java 和 Apache HttpClient 将附件发布到 confluence 时出现 404

c# - 我如何从 AtTask 下载文档?

postgresql - 在plpgsql中声明多个相同类型的变量有什么捷径吗?

java - 为什么这个程序的输出是-4? (Java - 数据类型字节)

c++ - 将 .so 合并到另一个 .so 中而不依赖?

c++ - 如何使用CMake生成moc_*.cpp文件