重复调用对象成员方法时,如何简化对象名的重复书写?
嘿,我来帮你搞定这两个测试类时的小问题,刚好都是我平时写代码时也会遇到的痛点!
一、简化重复调用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
相关产品推荐
相关产品推荐

