开发者

How can you modify an object without calling member functions?

At 3.10/10, the standard says:

An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can also be used to modify its referent under certain circumstances. [Example: a member function called for an object (9.3) can modify the object. ]

So, rvalues are non-modifiable except under certain circumstances. We're told that calling a member function is one of those开发者_如何学JAVA exceptions. This gives the idea that there are ways of modifying objects other than calling a member function. I can't think of a way.

How can one modify an object without calling a member function?


How can one modify an object [that's specified by an rvalue expression] without calling a member function?

I know of only one way to do that, namely to bind the object to a reference to const, and then cast away the const-ness.

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; }

This is because a temporary object is not const itself unless it is of const type, so the example above does not cast away original const-ness (which would be UB).

EDIT, added: Luc Danton’s answer showed another (non-general) way, namely where the temporary's construction stores some reference or pointer to the object in some accessible location.

Cheers & hth.,


This seems to be accepted:

struct T {
   int x;
};

int main() {
   T().x = 3;
}

I am slightly surprised that this works, because IIRC the LHS of op= must be an lvalue, yet the following implies that even T().x is an rvalue:

struct T {
   int x;
};

void f(int& x) {
   x = 3;
}

int main() {
   f(T().x);
}

Edit: As of 4.6, GCC does warn about T().x = 3: error: using temporary as lvalue.

I can't think of any other way to modify a class object other than through data member access or member function calls. So, I'm going to say... you can't.


Modifying a temporary and not through an lvalue to that temporary:

#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) );
}

I don't think it's correct to assume that rvalues of class types are non-modifiable. I now understand that paragraph as 'for non-class types, an lvalue for an object is needed in order to modify that object'.


I can think of one way:

If your class exposes public member variables, you can assign directly to those member variables. For example:

class A
{
    public:
        int _my_var;
...
};

int main(int argc, char** argv)
{
    A *a = new C();
    a->_my_var = 10;
}

This is not a good programming style though - exposing a member variable as public isn't something I would advocate or even suggest.

Also, if you can do something really weird, such as directly writing some address in memory, an offset from the pointer to the class object - but why would you do that?


How can one modify an object without calling a member function?

By assigning a value to one of the object's visible data members, of course.


Doing an implicit cast is sort of like calling a member function -- also modifying rvalue refs seems to work.

Tested the following in vc++10 and 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 */ }


A member function can change the member directly, but it can also delegate that responsibility:

struct Foo {
  int x;
  void Bar() { scanf("%d", &x); }
};

The current wording of the standard has the advantage that one doesn't need to argue whether this is a case of Bar changing the object. If we'd agree that scanf changes the object, then that's just another example.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜