How can you modify an object without calling member functions?

后端 未结 7 2431
不知归路
不知归路 2021-02-13 15:41

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

相关标签:
7条回答
  • 2021-02-13 16:11

    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.,

    0 讨论(0)
  • 2021-02-13 16:11

    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'.

    0 讨论(0)
  • 2021-02-13 16:11

    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 讨论(0)
  • 2021-02-13 16:12

    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.

    0 讨论(0)
  • 2021-02-13 16:28

    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?

    0 讨论(0)
  • 2021-02-13 16:29

    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 */ }
    
    0 讨论(0)
提交回复
热议问题