Apache C++ Standard Library User's Guide

## 25.2 Facet Lifetimes

In the `mythical` example in the previous section, we created two facet objects with operator `new` and incorporated them into locales, but we never deleted the facets with operator `delete`. This is poor coding for most objects, but for facet objects it is correct. Once a facet has been incorporated into a locale, the locale system takes over responsibility for deleting the facet when it is no longer needed, that is, when all locales that contain references to it have been destroyed.

This is a useful feature. For example, consider the following fragment:

    using namespace std;

    cout.imbue(locale(locale(),new numpunct_byname<char>("de_DE")));
         |     |      |        |
        (4)   (3)    (1)      (2)

What's happening here is fairly complex, so let's trace it out step by step:

1. We create a temporary locale object that is a copy of the current global locale.

2. We create a `std::numpunct` facet for a German locale.

3. We create another temporary locale which is a copy of the one created in `(1)`, but with its `std::numpunct` facet replaced by the facet created in `(2)`.

4. Using locale's copy constructor, we pass this locale by value to `std::cout.imbue`, which saves a copy of it in the stream object.

At the end of this operation, all the temporary objects are quietly destroyed, but a reference to the new `std::numpunct` facet remains behind in the locale object inside `std::cout`. Other functions can retrieve this object using `std::cout.getloc()`, and make copies of it and its facets. All in all, it would be a burden on an application to have to keep track of all this, in order to determine when it is safe to delete the `std::numpunct_byname` object. We can be grateful that the locale system takes care of this chore.

It is possible, but not recommended, to override this default behavior. The constructors of all the standard facets, and the constructor of the base class `std::locale::facet`, all take an integer parameter named `refs`, which defaults to `0` when you don't specify it. This is the usual case. If you specify it as `1` or some other positive integer, the locale system does not delete the facet.

This is necessary for facet objects that can't have the `delete` operator applied to them, for instance, because they were created on the stack or as static objects. To discourage you from creating facets this way, all the standard facets have protected destructors. The following code causes a compilation error:

    static std::numpunct<char> my_static_np(1);   // Error: no public
                                                  // destructor

    int main () {
      std::numpunct_byname<char> my_np("de_DE",1);  // Error: no public
                                                    // destructor
      ...
    }

You can circumvent this protection by deriving a class with a public destructor from the standard facet. This may seem reasonable if you are going to use it only as a stand-alone object, and do not plan to incorporate it into any locale. For example, the following code lets you retrieve some data from the standard `std::numpunct<char>` facet without the overhead of `new/delete`:

    class my_numpunct: public std::numpunct<char> { };
    int main() {
      my_numpunct np;
      std::cout << np.truename() << " or " << np.falsename()
                << '?' << std::endl;
      ...
    }

However, the following code accomplishes the same thing even faster, because `use_facet` is very fast compared to the cost of calling most facets' constructors:

    int main() {
      const std::numpunct<char>& np=
          std::use_facet<numpunct<char> >(std::locale::classic());
      std::cout << np.truename() << " or " << np.falsename()
                << '?' << std::endl;
      ...
    }

In short, while it is possible to create facet objects on the stack, there is rarely a reason to do so. It is probably better to adapt a consistent policy of always creating facet objects with operator `new`. If you incorporate the facet into a locale, you do not need to delete it, and indeed, deleting it would be an error. If you never incorporate it into any locale, you should delete it when you are finished with it. Instead of creating and deleting a stand-alone facet in this case, however, it is usually possible (and faster) to accomplish the same thing by retrieving a reference to an existing facet from some locale.