我有点困惑为什么我被告知要用c ++中的二元运算符而不是foo来返回const foo。

我一直在阅读Bruce Eckel的“Thinking in C ++”,在关于运算符重载的章节中,他说“通过使[重载二元运算符]的返回值为const,你声明只能为该返回值调用const成员函数。这是const-correct,因为它可以防止您将潜在有价值的信息存储在最有可能丢失的对象中。“

但是,如果我有一个返回const的加号运算符和一个前缀增量运算符,则此代码无效:

class Integer{
int i;

public:
    Integer(int ii): i(ii){ }
    Integer(Integer&);

    const Integer operator+();
    Integer operator++();
};


int main(){

Integer a(0);
Integer b(1);

Integer c( ++(a + b));
}

要允许这种赋值,让+运算符返回非const值是不是有意义?这可以通过添加const_casts来完成,但这会变得非常笨重,不是吗?

谢谢!

有帮助吗?

解决方案

当你说++ x时,你说“将x加1,将结果存回x,然后告诉我它是什么”。这是preincrement运算符。但是,在++(a + b)中,你应该如何“将结果存回一个+ b”?

当然你可以把结果存回到临时表中,而临时表现在持有+ b的结果,这很快就会消失。但是如果你真的不关心结果的存储位置,你为什么要增加它而不只是添加一个呢?

其他提示

仅供参考, ++(a + b)即使使用POD(普通旧数据类型,如 int )也是非法的。因此,不允许将它用于您自己的类类型也是有意义的。试试这个:

int a = 1;
int b = 2;
int c = ++(a+b);

GCC返回错误:左值作为递增操作数

在你的情况下,最好让你的拷贝构造函数采用 const Integer 参数,然后像这样创建 Integer c

Integer c(a + b + Integer(1));

复制构造函数通常采用 const 引用,为您解决该问题。

(非const复制ctor意味着一些资源的转移,这有时是有用的,但对于99%的情况,它是不需要的)

我相信OP的例子适用于如果加法运算符被任何其他返回引用的二元运算符替换的问题,例如赋值运算符:

Integer c( ++(a = b));

我来到这里想知道是否应该让我的赋值运算符返回一个const或一个非const引用。 一些教程使用非const版本,与“Thinking in C ++”的建议相反。 其他一些参考资料给出了理由:

  

请注意,返回的引用未声明为const。这可能有点令人困惑,因为它允许你写这样的疯狂的东西:

     
    

MyClass a,b,c;

         

...

         

(a = b)= c; //什么??

  
     

乍一看,你可能希望通过让operator =返回一个const引用来阻止这样的情况。但是,像这样的语句将适用于原始类型。更糟糕的是,一些工具实际上依赖于这种行为。因此,从operator =返回非const引用非常重要。经验法则是,“如果它对于整数来说足够好,那么它对于用户定义的数据类型就足够了。”

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top