的问题是,你有没有为A
和自分配B
至少调用赋值运算符(在这种情况下,默认的,由编译器生成)定义的拷贝构造函数/赋值运算符,它只需从返回的“A”实例中复制a
指针,然后当该实例被删除时,内存被释放,B
中的a
成员现在指向垃圾。如果你加点记录不难看出:
#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();
}
输出:
因此,要么实现适当的拷贝构造函数/赋值运算符,或使他们的一个/两个删在使用原始指针时转义拷贝。例如,添加A(const A&) = delete;
和A& operator=(const A&) = delete;
将使您的程序无法编译,然后您可以开始检查您要如何接近进行复制的位置。
这里最大的问题是语义。一种可能的方法“使这项工作”可能是:
#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;
}
但随后有问题 - 什么是复制操作的语义?转移指针的所有权?复制值?由于编译器无法回答这些问题,它只是复制成员。
你的问题到了一边,如果一个类有析构函数,它几乎肯定也应该有一个拷贝构造函数和赋值运算符。 –
由于你做了什么导致*未定义的行为*你可以期望*任何*。包括(但不限于)[鼻恶魔](http://catb.org/jargon/html/N/nasal-demons.html)。最有可能你会*只*有崩溃。如果你有右值或左值,这并不重要。 –
为了扩展@NeilButterworth的评论,你应该阅读[三,五和零的规则](http://en.cppreference.com/w/cpp/language/rule_of_three)。 –