现在我们讨论下使用返回指针的函数的潜在错误。假设有一个函数返回一个指向某个MyClass类型的对象的指针。
MyClass* MyFactoryClass::Create(const Inputs& inputs);
RefCountPtr<MyClass> MyFactoryClass::Create(const Inputs& inputs);
ScopedPtr<MyClass> MyFactoryClass::Create(const Inputs& inputs) { ScopedPtr<MyClass> result(new MyClass(inputs)); return result; //无法通过编译 }
ScopedPtr<MyClass> result;//创建一个空的作用域指针 //填充它 void MyFactoryClass::Create(const Inputs& inputs,ScopedPtr<MyClass>& result);
//返回一个指向一个结果的指针,调用者“并不拥有这个结果的所有权” MyClass* SomeClass::Find(const Inputs& inputs);
对于上述第一个问题,SomeClass类认为自己将负责删除它刚返回的那个指针所指向的MyClass实例,因此会在未来的某个时刻将它删除。在这种情况下,如果这个函数的用户将删除他所接收到的指针,这个实例将被删除不止一次,这显然不是个好主意。其次,这个实例可能是一个vector模板中使用new[]操作符(带方括号)创建的一个MyClass对象数组的一部分,而现在我们将使用不带方括号的delete操作符从这个数组中删除一个对象。这同样不是个好的做法。最后,MyClass实例可能是在堆栈上创建的,根本不应该使用delete操作符进行删除。
在这种情况下,任何试图删除我们并不拥有的对象的行为(直接删除,或者把它赋值给一个将接收对象所有权的任何类型的智能指针)将会导致灾难。返回这种指针的一种合适的方法是返回一个”半智能“指针,它并不拥有它所指向的对象的所有权。
总结:为了避免内存泄露,建议遵从以下规则:
原文:http://blog.csdn.net/kerry0071/article/details/37832981