Inheritance diagram for lfc::Ptr::
Public Methods | |
Ptr (T *p=NULL) throw () | |
construct an smart pointer from an build-in pointer. More... | |
Ptr (const Ptr &ptr) throw () | |
copy-constructor. More... | |
Ptr (Null) throw () | |
enable using lfcNull as a null smart pointer. More... | |
~Ptr () throw () | |
template<class X> | Ptr (const Ptr< X > &ptr) throw () |
enable smart pointer conversions. More... | |
const Ptr & | operator= (const Ptr &ptr) throw () |
assignment. More... | |
template<class X> const Ptr & | operator= (const Ptr< X > &ptr) throw () |
assignment with conversion. More... | |
const Ptr & | operator= (T *p) throw () |
assignment from dumb pointer. More... | |
template<class X> const Ptr< X > | dynamicCast () const throw () |
dynamic_cast equivalent. More... | |
bool | isNull () const throw () |
return true if smart pointers is null. More... | |
T * | operator-> () const |
indirect member selector. More... | |
T & | operator * () const |
dereference smart pointer. More... | |
T * | realPointer () const |
return the real pointer. More... |
This class implements a reference counting smart pointer. It is designed to look and feel as much as possible like build-in C++ pointers (note that there are some differences).
It is usually declared/initialised like this:
// normal declaration and initialization Ptr<T> sp1(new T(args)); // Ptr<T> corespond to T* build-in pointer // note that the constructor taking a T* is explicit, so: //Ptr<T> sp2 = new T(args); is not legal // you can declare a Ptr<T> object and init later: Ptr<T> sp3; sp3 = new T(args); // smart pointer to constant objects Ptr<const T> sp4 = sp3; // then you can use Ptr<T> objects much like normal pointers: sp3->method(args); (*sp3) = T_value;
Ptr<T> has a shared ownership on the object it points to, so more smart pointers can point to the same object (the smart pointers pointing to the same object may have different types, supporting type conversions similar (but not identical) to build-in pointers, so if T1* -> T2* then Ptr<T1> -> Ptr<T2>).
The pointed object is automaticaly deleted when there is no smart pointer pointing to it.
Take care when mixing Ptr<T> with build-in pointers because Ptr<T> assume ownership on the object pointed to. (also don't initialize a Ptr<T> with the address of an non-heap allocated objects)
Usage sample:
// smart pointer declarations Ptr<Base> sp1; // null initialized Ptr<Deriv> sp2(new Deriv); // point to new Base object Ptr<Base> sp3(sp2); // init form another smart ptr (note Deriv -> Base conversion) //Ptr<Base> sp4 = new Base; // fail: Ptr<T>(T*) is _explicit_ Ptr<Deriv> sp4 = lfcNull; // init to NULL (useful for func args) Ptr<const Base> sp5 = sp3; // Ptr to const object (note non-const -> const conversion) Ptr<double> sp6; // Ptr to a buid-in type // basic usage sp2->f(); sp2->x = 10; Deriv obj = *sp2; // sp1->f(); // will throw an exception (null dereferencing) // *sp1; // idem // copying and conversions // (similar to buil-in pointers, if T1* -> T2* then Ptr<T1> -> Ptr<T2>) sp1 = sp2; // ok, Ptr<Deriv> -> Ptr<Base> //sp2 = sp3; // fail, Ptr<Base> -> Ptr<Deriv> is illegal sp2 = sp2.dynamicCast<Deriv>(); // ok, dynamic cast (may return a null ptr) // comparations (2 smart ptr are equal if they point to the same object) sp1 == sp2; // false sp1 == sp3; // true sp1 == lfcNull; // true lfcNull == sp1; // true sp1.isNull(); // true // special usage Base *p = sp2.realPointer(); // use with caution! // now, all unreferenced objects // will be automaticaly deleted
improve this documentation
|
construct an smart pointer from an build-in pointer.
|
|
copy-constructor.
|
|
enable using lfcNull as a null smart pointer.
|
|
|
|
enable smart pointer conversions. you can convert Ptr<X> to Ptr<Y> <=> X* can be converted to Y* |
|
assignment.
|
|
assignment with conversion.
|
|
assignment from dumb pointer.
|
|
dynamic_cast equivalent.
|
|
return true if smart pointers is null.
|
|
indirect member selector. use this operator to use/call pointed object's members
|
|
dereference smart pointer.
|
|
return the real pointer.
|