Use smart pointers for ownership

Source: Internet
Author: User

Now we will discuss the potential errors of functions that return pointers. Assume that a function returns a pointer to an object of the myclass type.

MyClass* MyFactoryClass::Create(const Inputs& inputs);

A very obvious problem with this function is whether its caller is responsible for deleting this object? Or is the instance of the myclass class pointed to by this pointer owned by myfactoryclass? This problem should be explained in the header file that declares this function in the form of annotations. But in the world of software, it is rare to do so. However, even if the function author does provide a comment, it indicates that the function creates a new object on the stack and Its caller is responsible for deleting the object, we will find ourselves facing a situation where every time we receive a pointer to an object returned by a function call, we need to remember to check the annotation (or when there is no annotation, check the Code itself) to determine whether we are responsible for deleting this object. As mentioned above, we should rely more on compilers than programmers. Therefore, a reliable method to implement the ownership of this object is to let the function return a smart pointer. For example:

RefCountPtr<MyClass> MyFactoryClass::Create(const Inputs& inputs);

This design makes the ownership of the objects returned by the function uncontroversial and does not leave a chance of Memory leakage. On the other hand, if you think that the reference counting pointer speed is too slow, you can also return a scope pointer. However, a problem occurs: scopedptr <myclass> cannot be copied, so it cannot be returned according to the traditional method:

Scopedptr <myclass> myfactoryclass: Create (const inputs & inputs) {scopedptr <myclass> result (New myclass (inputs); return result; // compilation fails}

Therefore, the solution is as follows:

Scopedptr <myclass> result; // create an empty scope pointer // fill it with void myfactoryclass: Create (const inputs & inputs, scopedptr <myclass> & result );

We create a scope pointer containing null values and fill it with the myfactoryclass: Create () method. This method will not make the ownership of the object created by this function wrong. If you are not sure which pointer should be returned, you can choose one of the following schemes:

  • If needed, return a faster scopedptr and use its release () method to transfer ownership.
  • Two methods are used at the same time.
In another case, the someclass: Find () method returns a pointer to an object, but the user does not have ownership of the object:

// Returns a pointer to a result. The caller "does not have ownership of the result" myclass * someclass: Find (const inputs & inputs );

In this case, the pointer returned by this function points to an object inside someclass.

For the first problem above, the someclass class considers that it will be responsible for deleting the myclass instance pointed to by the pointer it just returned, so it will be deleted at some time in the future. In this case, if the user of this function deletes the pointer received by him, the instance will be deleted more than once, which is obviously not a good idea. Secondly, this instance may be part of a myclass object array created using the new [] Operator (with square brackets) in a Vector Template, now we will use the delete operator without square brackets to delete an object from this array. This is also not a good practice. Finally, the myclass instance may be created on the stack and should not be deleted using the delete operator.

In this case, any behavior that tries to delete an object that we do not own (delete it directly, or assign it to a smart pointer of any type that will receive the ownership of the object) this will cause a disaster. A proper way to return this pointer is to return a "semi-intelligent" pointer, which does not have the ownership of the object it points.

To avoid Memory leakage, follow these rules:

  • When an object is created using the new operator, the result is immediately assigned to a smart pointer (reference counting pointer or scope pointer is recommended)
  • Do not enclose square brackets when using the new operator. If you create an array, you can create a new vector template, which represents a single object.
  • Avoid loop reference
  • When writing a function that returns a pointer, it should return a smart pointer instead of the original pointer to implement the ownership of the result.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.