临时对象并传递(const / non-const)`value`

时间:2013-08-20 18:05:01

标签: c++ temporary-objects

临时对象的生命周期持续到使用without references时创建它的表达式的全长。

请考虑以下事项:

 class My
 {
   int i;
   public:
     void increment()
     {
       i++;
     }
 };

 My withOutConst()
 {
   return My();
 }

 const My withConst()
 {
   return My();
 }

 int main()
 {
   My ob;
   withOutConst().increment();  // Case 1
   withConst().increment();     // Case 2

   return 0;
 }

据我所知,编译器创建了一个temporary对象(类型为const My)来保存上述情况下的返回值。 而且,我正在尝试修改临时对象。

(1)编译好并且

(2)导致编译错误,错误:

error: passing 'const My' as 'this' argument of void My::increment() discards qualifiers

这意味着基本上this的类型为My而不是const My,因为它是non-const函数的调用。

我的问题:

我试图通过调用const My成员函数来修改non-const类型的临时对象。

那么为什么我在案例(1)中没有得到相同的错误,因为我在两种情况下都在const My类型的对象上操作。

我知道这与函数的return type有关,但我无法完全理解,因为最后它归结为试图修改类型的临时函数的函数(void My::increment())在这两种情况下const My

5 个答案:

答案 0 :(得分:2)

临时有一个类型,该类型可以是const,也可以是非const。您只能在非const对象上调用非const成员函数。 withOutConst()会产生My类型的临时格式,withConst()会产生const My类型的临时格式。

也许你误以为临时总是const?如果是这样,那就错了。

答案 1 :(得分:0)

  

那么为什么我不能在case(1)中得到相同的错误,因为我在两种情况下都在const My类型的对象上操作。

这根本不是真的。

 My withOutConst()
 {
   return My();
 }

 const My withConst()
 {
   return My();
 }

withOutConst返回My类型的对象,而withConst()返回类型为const My的对象。尽管在这两种情况下您都将它们用作临时值,但它们的基础类型Myconst My与函数签名完全一样。

答案 2 :(得分:0)

  1. 返回一个临时非const对象,调用它上面的函数,然后它超出范围。
  2. 返回一个临时的const对象,它不允许调用非const函数。
  3. 临时对象不一定是const。

答案 3 :(得分:0)

  

据我所知,编译器创建了一个临时对象(类型为const My),以便在上述情况下保存返回值。

没有。 withOutConst()的返回值不是const,因为您没有声明它const。观察到的行为来自于此。

作为 rvalue ,您可能会感到困惑const。在许多情况下, rvalue 无法修改;但你可以在一个上调用非常数成员函数。

答案 4 :(得分:0)

如果这是你想要在更复杂的代码库中尝试做的事情的简化版本,你仍然想在const对象上使用某种类型的计数器,那么你需要标记你的“i”变量作为“可变的”。像这样:

class My
{
   mutable int i;
public:
   void increment()
   {
      i++;
   }
};