简体   繁体   中英

What happen to pointer members of a class if I assign a rvalue to an object of that?

What should I expect for the value of Ba after the line B=B.foo(); ?

I expected Ba=44 but I got Ba=0. Is that make sense?

class A {   //here is a class A
   public:
     int *a;  

     A(){ a = new int; *a=22;}

     A foo(){ A anA;        //anA is an object of the class A
              *anA.a=44;
              return anA;
     }

     ~A(){ delete a;}

};

int main(){

     A B;

     B=B.foo();

     //What is the value of B.a at this line of the code
}

The problem is that you have not defined a copy constructor/assignment operator for A and since the assignment to B invokes at least the assignment operator (in this case the default one, generated by the compiler), it simply copies the a pointer from the returned 'A' instance, then when that instance is deleted the memory is freed and the a member in B now points to garbage. If you add a little logging it is easy to see that:

#include <cstdio>

class A 
{
public:
    int *a;

    A()
    {
        a = new int;
        printf("A::A(0x%p): a is 0x%p\n", this, a);
        *a = 22;
    }

    A foo()
    {
        A anA;
        *anA.a = 44;
        return anA;
    }

    ~A()
    {
        printf("A::~A(0x%p): a is 0x%p\n", this, a);
        delete a;
    }

};

int main(int argc, char** argv)
{
    A B;
    B = B.foo();
}

Output:

在此处输入图片说明

So either implement a proper copy constructor/assignment operator, or make one of them/both deleted to escape copying when using raw pointers. For example, adding A(const A&) = delete; and A& operator=(const A&) = delete; will make your program not compile, and then you can start to examine how you want to approach the places where copying takes place.

The biggest issue here is the semantics. A possible approach to "make this work" could be:

#include <cstdio>

class A 
{
public:
    int *a;

    A()
    {
        a = new int;
        printf("A::A()(0x%p): a is 0x%p\n", this, a);
        *a = 22;
    }

    A(const A& otherA)
    {
        a = new int;
        printf("A::A(const A& otherA)(0x%p): a is 0x%p\n", this, a);
        *a = *otherA.a;
    }

    A& operator=(const A& otherA)
    {
        printf("A::operator=(const A& otherA)(0x%p)\n", this);
        // What are the semantics here? Transfer ownership? Copy Value?
        *a = *otherA.a;
        return *this;
    }
    A foo()
    {
        A anA;
        *anA.a = 44;
        return anA;
    }

    ~A()
    {
        printf("A::~A(0x%p): a is 0x%p\n", this, a);
        delete a;
    }

};

int main(int argc, char** argv)
{
    {
        A B;
        B = B.foo();
        printf("B.a is %d\n", *B.a);
    }
    return 0;
}

But then there is the question - what are the semantics of the copy operation? Transfer the ownership of the pointer? Copy the value? Since the compiler cannot answer any on these, it just copies the members.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM