Objective C ++, 3rd edition, item 17: store the new objects (object) in standalone statements (independent statement) to Smar

Source: Internet
Author: User

Item 17: saves the new objects (object) to smart pointers in standalone statements (independent statement)

By Scott Meyers

Translator: fatalerror99 (itepub's nirvana)

Release: http://blog.csdn.net/fatalerror99/

Assume that we have a function for obtaining our processing priority (processing priority), and a second function for processing a dynamically allocated (dynamically assigned) widget based on priority (priority:

Int priority ();
Void processwidget (STD: tr1: shared_ptr <widget> PW, int priority );

Do not forget the famous saying that using objects to manage resources (Use object to manage resources) (see item 13), processwidget is dynamically allocated (dynamically allocated) widgets use a smart pointer (smart pointer) (here, it is a tr1: shared_ptr ).

Now consider a call to processwidget:

Processwidget (new widget, priority ());

It's slow. Don't call it like this. It cannot be compiled. Tr1: The Constructor (constructor) that obtains a raw pointer (bare pointer) from shared_ptr is explicit, therefore, there is no implicit conversion from raw pointer (bare pointer) returned by expression "new widget" to tr1: shared_ptr required by processwidget. However, the following code can be compiled:

Processwidget (STD: tr1: shared_ptr <widget> (New widget), Priority ());

Surprisingly, although we are using object-managed resources everywhere, this call may leak resources. Let's see how this happened and we will get some inspiration.

Before the compiler can generate a call to processwidget, they must calculate the value of arguments (real parameters) passed as parameters. The second arguments (real parameter) is just a call to the function priority, but the first arguments (real parameter) ("STD: tr1: shared_ptr <widget> (new widget )"), it consists of two parts:

  • Execute the expression "new widget.
  • A call to tr1: shared_ptr Constructor (constructor.

Therefore, before processwidget can be called, the compiler must generate code to do these three tasks:

  • Call priority.
  • Run "new widget ".
  • Call tr1: shared_ptr Constructor (constructor ).

The C ++ compiler allows a considerable range to determine the order in which these three tasks are completed. (The processing method is different from that in Java, C #, and other languages. In those languages, function parameters (function parameters) are always calculated in a specific order .) The "New widget" expression must be executed before the tr1: shared_ptr Constructor (constructor) can be called, because the result of this expression must be passed to tr1 as an argument (real parameter :: shared_ptr Constructor (constructor), but the call to priority can be executed in the first, second, or third. If the compiler chooses the second one to execute it (probably this will make them generate more efficient code), we finally get the operation order:

  1. Run "new widget ".
  2. Call priority.
  3. Call tr1: shared_ptr Constructor (constructor ).

However, consider what will happen if an exception (exception) is thrown by calling priority. In this case, the pointer (pointer) returned from "new widget" is lost because it is not saved to tr1: shared_ptr that we expect to prevent resource leaks (resource leakage. An exception may be inserted between the time when a resource is created and the time when the resource is handed over to a resource-management object, therefore, a leakage may occur in the call to processwidget.

The method to avoid similar problems is simple: Create a widget with a separate statement and store it into a smart pointer (smart pointer), and then pass the smart pointer (smart pointer) to processwidget:

STD: tr1: shared_ptr <widget> Pw (new widget); // Store newed object
// In a smart pointer in
// Standalone statement

Processwidget (PW, Priority (); // This call won't leak

This can work because the compiler has much less room to reschedule the operation sequence among different statements than within one statement. In the modified Code, the "new widget" expression and the call to the tr1: shared_ptr Constructor (constructor) are different from the call to the priority in the statement, therefore, the compiler will not allow calls to priority to be inserted into them.

Things to remember

  • Store the new object to smart pointers in standalone statements (independent statement ). If you neglect this, when exceptions are thrown, subtle resource leaks may occur ).

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.