如果我为一个对象分配一个右值,那么类的指针成员会发生什么?

时间:2017-02-25 17:07:40

标签: c++ class pointers

在B = B.foo()之后,我应该对B.a的值有什么期望; ?

我预计B.a = 44但我得到B.a = 0。这有道理吗?

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
}

1 个答案:

答案 0 :(得分:3)

问题是你没有为A定义一个拷贝构造函数/赋值运算符,因为赋值给B至少会调用赋值运算符(在这种情况下是默认值,由编译器),它只是从返回的' A'中复制a指针。实例,然后当该实例被删除时,内存被释放,a中的B成员现在指向垃圾。如果添加一点日志记录,很容易看出:

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

输出:

enter image description here

因此,在使用原始指针时,要么实现正确的复制构造函数/赋值运算符,要么删除其中一个/两者以避免复制。例如,添加A(const A&) = delete;A& operator=(const A&) = delete;将使您的程序无法编译,然后您可以开始检查您希望如何接近复制的位置。

这里最大的问题是语义。一种可能的方法来实现这项工作&#34;可能是:

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

但是有一个问题 - 复制操作的语义是什么?转移指针的所有权?复制价值?由于编译器无法回答任何问题,因此只会复制成员。