在c++中操作重载赋值运算符

Operating overloading the assignment operator in c++

本文关键字:重载 赋值运算符 操作 c++      更新时间:2023-10-16

我最近一直在做一个fraction类,重载运算符时没有得到预期的结果,我不知道为什么。希望有人能帮上忙。我尝试只包含相关代码。

const fraction fraction::operator* (fraction frac)
{
    return fraction(frac.numerator * numerator, frac.denominator * denominator);
}
const fraction fraction::operator* (int num)
{
    return fraction(numerator*num, denominator);
}
fraction& fraction::operator= (const fraction &rightSide)
{
    return *this;
}

我发现这些操作是正确的(其中frac#是一个分数对象):

frac1 = frac2;
frac3 = frac4 * 2;
frac5 = frac6 * frac7;

上述操作按预期进行,但以下操作使frac8与初始化时一样:

fraction frac8(4, 5); // Initializes a fraction, setting numerator = 4, denominator = 5
frac8 = frac8 * 3; // This doesn't quite work, leaving frac8 with the original numerator/denominator

我只是不明白为什么frac3=frac4*2有效,而frac8=frac8*3无效。有什么想法吗?我发现在赋值运算符中使用const关键字不是解决方案。

如果你在operator=体内只做return *this;,你怎么会期望它做任何有用的事情?您必须将rightSide的字段分配给this的字段。

但是,更重要的是,如果您的类不管理在发生复制时需要特殊处理的资源,您可以使用编译器提供的赋值运算符。它只是将一个实例的字段复制到另一个实例中,对于fraction类来说,这似乎非常好。

顺便说一句,通常使用复合运算符来实现"正则"运算符;您可能想看看运算符重载FAQ。

您的赋值都不起作用,因为赋值运算符实现是空的,除了返回对其左侧的引用外,什么也不做。

也就是说,这三项任务都没有

frac1 = frac2;
frac3 = frac4 * 2;
frac5 = frac6 * frac7;

真的很管用。

出于某种原因,你声称以上作业"有效",但这一定是你的困惑。它们不"工作"。frac8 = frac8 * 3也没有,原因完全相同。

p.S.我怀疑你的"工作"声明实际上是这样写的

fraction frac1 = frac2;
fraction frac3 = frac4 * 2;
fraction frac5 = frac6 * frac7;

这可能确实有效。但这种语法与赋值运算符无关。在这种情况下不使用赋值运算符。此语法对应于复制初始化。它依赖于类的复制构造函数(至少在概念上),而不是赋值运算符。这就是为什么它可能起作用,而真正的赋值不起作用,因为您将其设为空,从而"丧失"了复制赋值运算符的能力。

您的赋值运算符只返回对象本身(即*this)。。。所以在上一个例子中,它只是一个no-op,而不是从右侧对象执行实际的赋值操作。换句话说,临时fraction对象是由operator*创建的,但由于赋值运算符不会复制右侧对象的值,因此在operator=方法完成后,您最终只会丢弃operator*生成的临时fraction实例。

顺便说一句,当涉及到创建用户生成的赋值运算符时,您可能需要研究三规则。它基本上声明,如果类中的资源需要用户生成的赋值运算符,那么还应该实现用户定义的复制构造函数和析构函数。。。如果需要管理的资源超出了编译器对这些方法的默认实现中所实现的资源,那么编译器为后两个项生成的默认值就不够了。