More C++ Idioms/Const auto ptr
Const auto_ptr[edit | edit source]
Intent[edit | edit source]
To prevent transfer of ownership of a held resource. Note: auto_ptr has been deprecated and is replaced by shared_ptr, unique_ptr and weak_ptr in C++11, thereby this idiom is no longer suggested.
Also Known As[edit | edit source]
Motivation[edit | edit source]
Often it is desirable to enforce a design decision of non-transferable ownership in code and enforce it with the help of compiler. Ownership in consideration here is of any resource such as memory, database connections and so on. const auto_ptr idiom can be used if we don't want ownership of the acquired resource to be transfered outside the scope or from one object to the another.
auto_ptr without any cv-qualifier (fancy name for const and volatile) has move semantics as described in the Move Constructor idiom. It basically means that ownership of memory is unconditionally transferred from right hand side object to the left hand side object of an assignment, but it ensures that there is always a single owner of the resource. const auto_ptr can prevent the transfer.
Solution and Sample Code[edit | edit source]
Declare the auto_ptr holding memory resource as const.
const auto_ptr <X> xptr (new X()); auto_ptr <X> yptr (xptr); // Not allowed, compilation error. xptr.release(); // Not allowed, compilation error. xptr.reset( new X() ); // Not allowed, compilation error.
Compiler issues a warning here because the copy-constructor of yptr is not really a copy-constructor but in fact it is a move constructor, which takes a non-const reference to an auto_ptr, as given in Move Constructor idiom. A non-const reference can't bind with a const variable and therefore, compiler flags an error.
Consequences[edit | edit source]
- An undesirable consequence of const auto_ptr idiom is that compiler can't provide a default copy-constructor to a class that has a const auto_ptr member in it. This is because the compiler generated copy-constructor always takes a const RHS as a parameter, which can't bind with a non-const move constructor of auto_ptr. The solution is to use Virtual Constructor idiom or use boost::scoped_ptr, which explicitly prohibits copying by denying access to assignment and copy-constructor.