You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++17中创建可自动钳位0.0-360.0的类类型(行为同double)

解决方案

完整实现代码

#include <iostream>
#include <algorithm> // 用于std::clamp(C++17支持)

class degree {
private:
    double value;

    // 静态辅助函数:钳位值到[0.0, 360.0]
    static double clamp(double val) {
        return std::clamp(val, 0.0, 360.0);
    }

public:
    // 构造函数:初始化时钳位
    degree(double val = 0.0) : value(clamp(val)) {}

    // 拷贝构造与移动构造
    degree(const degree& other) = default;
    degree(degree&& other) = default;

    // 赋值运算符:处理double和degree类型的赋值,都钳位
    degree& operator=(double val) {
        value = clamp(val);
        return *this;
    }

    degree& operator=(const degree& other) = default;
    degree& operator=(degree&& other) = default;

    // 隐式转换为double,无需getter
    operator double() const {
        return value;
    }

    // 算术运算符重载:运算后钳位
    degree operator+(double val) const {
        return degree(value + val);
    }

    degree operator-(double val) const {
        return degree(value - val);
    }

    degree operator*(double val) const {
        return degree(value * val);
    }

    degree operator/(double val) const {
        return degree(value / val);
    }

    // 与degree类型的运算
    degree operator+(const degree& other) const {
        return degree(value + other.value);
    }

    degree operator-(const degree& other) const {
        return degree(value - other.value);
    }

    degree operator*(const degree& other) const {
        return degree(value * other.value);
    }

    degree operator/(const degree& other) const {
        return degree(value / other.value);
    }

    // 复合赋值运算符
    degree& operator+=(double val) {
        value = clamp(value + val);
        return *this;
    }

    degree& operator-=(double val) {
        value = clamp(value - val);
        return *this;
    }

    degree& operator*=(double val) {
        value = clamp(value * val);
        return *this;
    }

    degree& operator/=(double val) {
        value = clamp(value / val);
        return *this;
    }

    degree& operator+=(const degree& other) {
        value = clamp(value + other.value);
        return *this;
    }

    degree& operator-=(const degree& other) {
        value = clamp(value - other.value);
        return *this;
    }

    degree& operator*=(const degree& other) {
        value = clamp(value * other.value);
        return *this;
    }

    degree& operator/=(const degree& other) {
        value = clamp(value / other.value);
        return *this;
    }
};

// 重载输出运算符,方便打印
std::ostream& operator<<(std::ostream& os, const degree& deg) {
    os << static_cast<double>(deg);
    return os;
}

int main() {
    degree my_num1 = 3.5;
    std::cout << "my_num1 = " << my_num1 << "\n"; // 输出3.5

    degree my_num2 = 400.8;
    std::cout << "my_num2 = " << my_num2 << "\n"; // 输出360.0

    degree my_num3 = -5.1;
    std::cout << "my_num3 = " << my_num3 << "\n"; // 输出0.0

    my_num3 = my_num2 - my_num1;
    std::cout << "my_num3 = my_num2 - my_num1 = " << my_num3 << "\n"; // 输出356.5

    // 额外测试复合赋值
    my_num3 += 10.0;
    std::cout << "my_num3 +=10.0 = " << my_num3 << "\n"; // 输出360.0

    my_num3 -= 400.0;
    std::cout << "my_num3 -=400.0 = " << my_num3 << "\n"; // 输出0.0

    return 0;
}

关键部分解释

  • 钳位逻辑:借助C++17标准库的std::clamp函数,一键实现值的范围限制,确保所有操作后的结果都落在0.0到360.0之间。
  • 隐式转换到double:通过operator double() const重载,让degree对象可以直接当作double使用,比如直接输出、参与其他double类型的运算,完全不需要getter方法。
  • 构造与赋值处理:所有构造函数和赋值运算符都会先对输入值进行钳位,保证对象从创建到修改的每一步,内部值都合法。
  • 完整运算符重载:覆盖了常用的算术运算符(+、-、*、/)和复合赋值运算符(+=、-=等),同时支持degree与degree、degree与double之间的运算,运算结果自动钳位,让degree的使用体验和原生double几乎一致。
  • 简化实现:不需要模板,因为我们只需要封装double类型,去掉不必要的泛型逻辑,代码更简洁易懂。

测试验证

运行上述代码后,输出结果完全符合预期:

my_num1 = 3.5
my_num2 = 360
my_num3 = 0
my_num3 = my_num2 - my_num1 = 356.5
my_num3 +=10.0 = 360
my_num3 -=400.0 = 0

内容的提问来源于stack exchange,提问作者Invader88

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 05:07:33