3.10 / 10,标准说:
对象的左值是必要的,以便修改对象,除了在某些情况下也可以使用类类型的右值来修改其指示对象。 [示例:调用对象(9.3)的成员函数可以修改对象。 ]
因此,除非在某些情况下,否则rvalues是不可修改的。我们被告知调用成员函数是其中一个例外。这给出了除了调用成员函数之外还有修改对象的方法的想法。我想不出办法。
如何在不调用成员函数的情况下修改对象?
答案 0 :(得分:3)
如何在不调用成员函数的情况下修改对象[由rvalue表达式指定]?
我只知道一种方法,即将对象绑定到const
的引用,然后抛弃const
-
E.g。
template< class Type >
Type& tempRef( Type const& o ) { return const_cast< Type& >( o ); }
struct S { int x; };
int main()
{ tempRef( S() ).x = 3; }
这是因为临时对象本身不是const
,除非它是const
类型,因此上面的示例不会丢弃原始const
- ness(这将是UB)
编辑,补充说:Luc Danton的答案显示了另一种(非一般)方式,即临时的构造在某个可访问的位置存储一些引用或指向对象的指针。< / p>
干杯&amp;第h。,
答案 1 :(得分:2)
struct T {
int x;
};
int main() {
T().x = 3;
}
我有点惊讶这是有效的,因为IIRC op=
的LHS必须是左值,但以下暗示even T().x
is an rvalue:
struct T {
int x;
};
void f(int& x) {
x = 3;
}
int main() {
f(T().x);
}
修改:自4.6起,GCC 警告T().x = 3
:error: using temporary as lvalue
。
除了通过数据成员访问或成员函数调用之外,我无法想到修改类对象的任何其他方法。所以,我要说...... 你不能。
答案 2 :(得分:1)
修改临时而非通过左值的临时值:
#include <cstring>
class standard_layout {
standard_layout();
int stuff;
};
standard_layout* global;
standard_layout::standard_layout()
{ global = this; }
void
modify(int)
{
std::memset(global, 0, sizeof *global);
}
int
main()
{
modify( (standard_layout {}, 0) );
}
我不认为假设类类型的rvalues是不可修改的是正确的。我现在理解该段落为'对于非类类型,为了修改该对象需要对象的左值'。
答案 3 :(得分:0)
我可以想到一种方式:
如果您的类公开公共成员变量,您可以直接分配给这些成员变量。例如:
class A
{
public:
int _my_var;
...
};
int main(int argc, char** argv)
{
A *a = new C();
a->_my_var = 10;
}
这不是一个好的编程风格 - 将成员变量公开为公开并不是我所倡导甚至建议的。
另外,如果你可以做一些非常奇怪的事情,比如直接在内存中写一些地址,从指向类对象的指针偏移 - 但为什么要这样做呢?
答案 4 :(得分:0)
如何在不调用成员函数的情况下修改对象?
当然,通过为一个对象的可见数据成员赋值。
答案 5 :(得分:0)
执行隐式转换有点像调用成员函数 - 修改rvalue refs似乎也有效。
在vc ++ 10和g ++ 4.4中测试了以下内容。
struct b { int i; b(int x) : i(x) {} };
struct a { int i; a() : i(0) { } operator b() { return i++ /* this works */, b(i); } };
a f(a&& x) { return x.i++ /* this works */, x; }
int main() { b b = f(a()); /* implicit operator b() cast; b.i will equal 2 */ }
答案 6 :(得分:-1)
成员函数可以直接更改成员,但也可以委派该职责:
struct Foo {
int x;
void Bar() { scanf("%d", &x); }
};
该标准的当前措辞具有以下优点:人们不需要争论这是否是Bar
改变对象的情况。如果我们同意scanf
更改对象,那么这只是另一个例子。