类中operator*运算符实现报错求助:float*x^int类型类乘法问题
usuario类operator*运算符实现导致程序崩溃
实现表示float*x^int类型的usuario类时,在实现operator*运算符后,执行两个类对象相乘、类对象与float类型相乘操作时程序终止报错。以下是完整代码:
主文件
#include <iostream> #include "usuario.h" usuario& operator*(usuario& u1,usuario& u2); usuario& operator*(usuario& u1,float num); int main() { usuario u1; usuario u2; std::cout<<"Monomio 1:"; std::cin>>u1; std::cout<<std::endl<<"Monomio 2:"; std::cin>>u2; float alfa = 3.2; usuario u3 = u1*u2; usuario u4 = u1; std::cout<<u1<<"*"<<u2<<"="<<u3<<std::endl; std::cout<<u1<<"*"<<alfa<<"="<<u4; return 0; } usuario& operator*(usuario& u1,usuario u2) { u1*=u2; return u1; } usuario& operator*(usuario& u1,float num) { usuario u2(num,0); u1*=u2; return u1; }
类头文件(usuario.h)
#ifndef USUARIO_H #define USUARIO_H #include <iostream> class usuario { public: usuario(); usuario(float numero, int exponente); usuario(const usuario& u); usuario& operator=(const usuario& u); usuario& operator*=(const usuario& u); float num() const; int exp() const ; private: float numero; int exponente; }; std::istream& operator>>(std::istream& in, usuario& u); std::ostream& operator<<(std::ostream& out,const usuario& u); #endif // USUARIO_H
实现文件
#include "usuario.h" usuario::usuario():numero(1),exponente(1) { } usuario::usuario(float numero, int exponente):numero(numero),exponente(exponente) { } usuario::usuario(const usuario& u):numero(u.numero),exponente(u.exponente) { } usuario& usuario::operator*=(const usuario& u) { numero*=u.numero; exponente+=u.exponente; return *this; } std::istream& operator>>(std::istream& in ,usuario& u) { char ch; float numero; int exponente; in>>numero; in>>ch; in>>ch; in>>exponente; u = usuario(numero,exponente); return in; } std::ostream& operator<<(std::ostream& out,const usuario& u) { out<<u.num(); out<<"x"; out<<"^"; out<<u.exp(); return out; } float usuario::num()const { return numero; } int usuario::exp()const { return exponente; } usuario& usuario::operator=(const usuario& u) { numero = u.numero; exponente = u.exponente; return *this; }
问题根源
- operator*设计错误:当前实现的
operator*直接修改左操作数(u1)并返回其引用,违背乘法运算语义——乘法不应改变原操作数,而是生成新的结果对象。这种设计会导致原对象被意外修改,若操作数为临时对象还可能引发悬垂引用问题。 - 声明与定义不匹配:主文件中
operator*(usuario& u1, usuario& u2)的声明与定义usuario& operator*(usuario& u1, usuario u2)的第二个参数类型不一致(声明为引用,定义为值传递),会引发编译或链接错误。 - 缺少const修饰:参数未使用
const引用,既无法接受临时对象作为操作数,也无法保证原对象不被修改。 - 缺少反向重载:未实现
float * usuario的重载,无法支持3.2 * u1这类右操作数为类对象的乘法。
修复方案
1. 修改operator*的实现,返回新对象而非引用
在usuario.h中补充正确的声明:
// 两个usuario对象相乘 usuario operator*(const usuario& u1, const usuario& u2); // usuario与float相乘 usuario operator*(const usuario& u, float num); // float与usuario相乘(反向重载) usuario operator*(float num, const usuario& u);
在实现文件中添加这些重载的实现:
usuario operator*(const usuario& u1, const usuario& u2) { usuario result = u1; result *= u2; return result; } usuario operator*(const usuario& u, float num) { usuario result(u.num() * num, u.exp()); return result; } usuario operator*(float num, const usuario& u) { return u * num; }
2. 移除主文件中原错误的operator*声明与定义
删除主文件中以下内容:
usuario& operator*(usuario& u1,usuario& u2); usuario& operator*(usuario& u1,float num); // 对应的错误实现 usuario& operator*(usuario& u1,usuario u2) { u1*=u2; return u1; } usuario& operator*(usuario& u1,float num) { usuario u2(num,0); u1*=u2; return u1; }
3. 输入逻辑优化(可选)
若输入格式不符合系数x^指数,operator>>会读取失败导致对象状态异常,可添加校验:
std::istream& operator>>(std::istream& in ,usuario& u) { char ch1, ch2; float numero; int exponente; if (!(in >> numero >> ch1 >> ch2 >> exponente) || ch1 != 'x' || ch2 != '^') { in.setstate(std::ios::failbit); return in; } u = usuario(numero, exponente); return in; }
修复后效果
修改后,u1*u2会生成新的usuario对象赋值给u3,u1和u2的原值保持不变;u1*alfa也会生成新对象,不会修改u1,完全符合乘法运算的预期。
内容的提问来源于stack exchange,提问作者Alvaro Suarez Menendez
相关产品推荐
相关产品推荐

