当我编译以下代码时:
#include <cstdio>
char retChar(){
return 'c';
}
int main(){
retChar() = 'f';
}
我收到以下错误:
modify.cpp: In function ‘int main()’:
modify.cpp:8:14: error: lvalue required as left operand of assignment
我已经搜索了与此错误类似的问题,但答案似乎只是针对具体情况。而且我还没有找到问题的答案(也许在其他地方?)
==================================================== ============================
但在以下情况下:
#include <iostream>
class int_Bag{
int a;
int b;
public:
int_Bag(const int x, const int y);
int_Bag(const int_Bag&c);
int_Bag& operator =(const int_Bag &c){
std::cout<< "copy assignment constructor called\n";
a = c.a;
b = c.b;
return *this;
}
~int_Bag();
void debug();
};
int_Bag::int_Bag(const int x, const int y):a(x),b(y){}
int_Bag::~int_Bag(){
std::cout<< "destructor called\n";
}
int_Bag::int_Bag(const int_Bag&c):a(c.a),b(c.b){
std::cout<< "copy constructor called\n";
}
int_Bag getBag(const int_Bag &c){
return c;
}
void int_Bag::debug(){
std::cout << a <<"," << b << std::endl;
}
int main(){
int_Bag *bag1 = new int_Bag(3,4);
int_Bag *bag2 = new int_Bag(5,6);
std::cout<< "assignment expression begins\n";
getBag(*bag1) = *bag2;
bag1->debug();
delete bag1;
delete bag2;
}
该程序可以编译并运行良好:
assignment expression begins
copy constructor called
copy assignment constructor called
destructor called
3,4
destructor called
destructor called
从结果中我们可以看到,当执行getBag()时,将通过调用副本构造函数来创建一个临时对象。因此,我认为在第一种情况下,分配不起作用的原因不仅仅是因为返回的char是临时的。
为什么作业getBag(*bag1) = *bag2;
在这里起作用?
这两种情况之间的赋值表达有什么区别?
我想对于第二种情况,整个赋值表达式分为两个步骤:首先调用getBag(),然后调用复制赋值,将* bag2复制到getBag()返回的新创建的临时对象中。但是,在第一种情况下,retChar()返回一个rvalue(也是临时的),该值只能出现在作业的RHS上,如@Jonathan Leffler所说。
第一种情况单独存在似乎只是一个愚蠢的问题(我看到那些负面评论)。我刚才添加的那些问题实际上是我真正困惑的地方。
期待收到有关我的假设和其他答案的评论。
(来自C ++初学者^^)
您不能将其分配给类似函数的结果。该函数返回一个r值,该值只能出现在分配的RHS中。与可以分配给它的l值进行对比。
如果您确实想(尽管可能不想这样做),则可以这样写:
char *retChar(){
static char c = 'c';
return &c;
}
int main(){
*retChar() = 'f';
}
现在,您已经修改了函数内部的变量retChar()
。
这段代码可以为您的示例提供更详尽的信息:
#include <iostream>
class int_Bag
{
int a;
int b;
public:
int_Bag(const int x, const int y);
int_Bag(const int_Bag&c);
int_Bag& operator =(const int_Bag &c){
std::cout<< "copy assignment constructor called:\nold";
this->debug();
std::cout << "new";
c.debug();
a = c.a;
b = c.b;
return *this;
}
~int_Bag();
void debug() const;
};
int_Bag::int_Bag(const int x, const int y) : a(x), b(y)
{
std::cout << "basic(" << x << "," << y << ")\n";
}
int_Bag::~int_Bag()
{
std::cout << "destructor called";
this->debug();
}
int_Bag::int_Bag(const int_Bag &c) : a(c.a), b(c.b)
{
std::cout << "copy constructor called";
this->debug();
}
int_Bag getBag(const int_Bag &c)
{
std::cout << "getBag returns";
c.debug();
return c;
}
void int_Bag::debug() const
{
std::cout << "(" << a << "," << b << ")" << std::endl;
}
int main()
{
int_Bag *bag1 = new int_Bag(3, 4);
int_Bag *bag2 = new int_Bag(5, 6);
std::cout << "assignment expression begins\n";
getBag(*bag1) = *bag2;
std::cout << "assignment expression ended\n";
bag1->debug();
delete bag1;
delete bag2;
}
当我运行它时,输出为:
basic(3,4)
basic(5,6)
assignment expression begins
getBag returns(3,4)
copy constructor called(3,4)
copy assignment constructor called:
old(3,4)
new(5,6)
destructor called(5,6)
assignment expression ended
(3,4)
destructor called(3,4)
destructor called(5,6)
该值5,6
被分配给由创建/返回的临时值getBag()
,但随后被销毁。这些都不会影响中的原始3,4
值*bag1
。由创建的(匿名)对象getBag()
可以使用直到它出现在完整表达式的末尾,但不能超过此范围,因此整个分配仍然非常可疑。
我在Mac OS X 10.9.1 Mavericks上使用G ++ 4.8.2或在Ubuntu 13.10上使用G ++ 4.8.1进行编译,在两种情况下均使用以下选项:
g++ -O3 -g -std=c++11 -Wall -Wextra -Werror intbag.cpp -o intbag
编译器没有丝毫杂音,valgrind
内存访问模式丝毫也没有干扰3.8.1。
我认为C ++可以为您提供足够的帮助,使您可以用脚射击,或者使用类似的混合比喻。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句