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

重复调用对象成员方法时,如何简化对象名的重复书写?

嘿,我来帮你搞定这两个测试类时的小问题,刚好都是我平时写代码时也会遇到的痛点!

一、简化重复调用comparator1的写法

你完全可以用两种方式来减少重复书写对象名的麻烦:

1. 给对象起个短别名

用auto&给原对象创建一个引用别名(避免拷贝,性能更好),之后用别名调用所有方法就行:

auto& cmp = comparator1;
cmp.setA(78.321);
cmp.showA();
cmp.setB('c');
cmp.setB("Yes");
cmp.setB(124.213);
cmp.showB();
cmp.setB(12);

2. 实现链式调用(更适合快速测试)

如果你的成员函数返回对象本身的引用,就能把所有调用连写成一行,测试时效率拉满。只需要修改你的类成员函数,让它们返回*this:

class numberComparator {
private:
    // 假设你的成员变量定义在这里
    double a;
    // 其他类型的b存储逻辑(比如用std::variant)

public:
    numberComparator& setA(double val) {
        a = val;
        return *this; // 返回当前对象的引用
    }

    numberComparator& showA() {
        std::cout << "A的值是:" << a << std::endl;
        return *this;
    }

    // 同理修改所有setB和showB重载函数
    numberComparator& setB(char val) {
        // 处理char类型的逻辑
        return *this;
    }

    numberComparator& setB(const char* val) {
        // 处理字符串的逻辑
        return *this;
    }

    numberComparator& setB(double val) {
        // 处理double类型的逻辑
        return *this;
    }

    numberComparator& setB(int val) {
        // 处理int类型的逻辑
        return *this;
    }

    numberComparator& showB() {
        // 输出B的当前值逻辑
        return *this;
    }
};

之后调用时就可以写成这样一行:

comparator1.setA(78.321).showA().setB('c').setB("Yes").setB(124.213).showB().setB(12);

二、处理重载时的类型不匹配输入

这个问题要分编译时和运行时两种场景来解决:

1. 编译时:阻止错误类型的调用

C的重载是编译时决议的,如果传入的类型和重载的参数类型不匹配,编译器会尝试隐式转换,转换失败就会报错。如果你想严格限制能传入的类型,可以用C20的requires表达式来过滤:

class numberComparator {
public:
    // 只允许int类型传入setB
    void setB(int val) requires std::is_same_v<decltype(val), int> {
        // 你的逻辑
    }

    // 只允许double类型
    void setB(double val) requires std::is_same_v<decltype(val), double> {
        // 你的逻辑
    }
};

这样如果传入不允许的类型(比如float或者自定义类),编译器会直接报错,提前帮你拦截错误。

2. 运行时:处理动态输入的类型错误

如果是处理用户输入(比如从控制台读入字符串),需要手动判断输入是否能转换成目标类型:
比如要把用户输入转换成int,可以用try-catch捕获std::stoi的异常:

std::string user_input;
std::cout << "请输入一个整数:";
std::cin >> user_input;

try {
    int val = std::stoi(user_input);
    comparator1.setB(val);
} catch (const std::invalid_argument&) {
    std::cerr << "错误:输入不是有效的整数!" << std::endl;
} catch (const std::out_of_range&) {
    std::cerr << "错误:输入的整数超出范围!" << std::endl;
}

或者用std::strtol来检查转换状态(不需要异常处理):

std::string user_input;
std::cin >> user_input;
char* end_ptr;
long val = std::strtol(user_input.c_str(), &end_ptr, 10);

// 如果end_ptr指向输入的开头,说明没有转换成功;或者转换后还有剩余字符,也说明输入无效
if (end_ptr == user_input.c_str() || *end_ptr != '\0') {
    std::cerr << "错误:输入不是有效的整数!" << std::endl;
} else {
    comparator1.setB(static_cast<int>(val));
}

内容的提问来源于stack exchange,提问作者A. Ortiga

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:22:03