临时对象的生命周期持续到使用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
。
答案 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
的对象。尽管在这两种情况下您都将它们用作临时值,但它们的基础类型My
和const My
与函数签名完全一样。
答案 2 :(得分:0)
临时对象不一定是const。
答案 3 :(得分:0)
据我所知,编译器创建了一个临时对象(类型为
const My
),以便在上述情况下保存返回值。
没有。 withOutConst()
的返回值不是const
,因为您没有声明它const
。观察到的行为来自于此。
作为 rvalue ,您可能会感到困惑const
。在许多情况下, rvalue 无法修改;但你可以在一个上调用非常数成员函数。
答案 4 :(得分:0)
如果这是你想要在更复杂的代码库中尝试做的事情的简化版本,你仍然想在const对象上使用某种类型的计数器,那么你需要标记你的“i”变量作为“可变的”。像这样:
class My
{
mutable int i;
public:
void increment()
{
i++;
}
};