Reputation: 16827
I'm a long time user of the boost::smart_ptr
library and love it. Like all boost libraries it is design to work well with the C++ Standard Library. Which usually is a great thing.
Unfortunately, I'm facing a situation were I need to be completely independent of the standard library. Despite this I would need the same kind of functionality as that offered by the boost::smart_ptr
(except, obviously every thing that has to do with std::). This includes amongst others, retain count, overloading of the bool and -> operators, relationships between week_ptr
and shared_ptr
etc.
Has anyone been faced with this situation? I'm looking into using the boost::smart_ptr
as a starting point and replacing/eliminating std::
related things. But looking at the complexity, am increasingly concerned about breaking things.
Upvotes: 1
Views: 335
Reputation: 1108
A classical in reference counting. Some basic code would look like this (shortest code I have managed to produce). Should be straightforward unless you know nothing about reference counting.
template <class CL>
struct refCount {
refCount() : nlinks_(1) , p_(0) {}
refCount(CL*p) : nlinks_(1) , p_(p) {}
~refCount() { if (!nlinks_) delete p_;}
size_t nlinks_;
CL* p_;
};
template <class CL>
class mySmartPtr {
public:
mySmartPtr() : rc_(new refCount<CL>()) {}
mySmartPtr(CL* p) : rc_(new refCount<CL>(p)) {}
mySmartPtr(const mySmartPtr<CL> & otherSmartPtr) : rc_(otherSmartPtr.rc_) { rc_->nlinks_++ ;}
mySmartPtr & operator=(const mySmartPtr<CL> & otherSmartPtr) {
otherSmartPtr.rc_->nlinks_++;
if (!(-- rc_->nlinks_)) delete rc_;
rc_ = otherSmartPtr.rc_;
return *this;}
CL& operator *() {return * rc_->p_ ; }
~mySmartPtr() { if(!(--rc_->nlinks_)) delete rc_;}
// commented to print #links (remove it)
// protected:
refCount<CL> *rc_;
};
A little (big) more work is needed if you need dynamic/static casts (thread safety).
Example of use:
int main()
{
mySmartPtr<int> i;
i = mySmartPtr<int>(new int(1));
*i = 7;
mySmartPtr<int> j(new int(3));
j = i;
std::cout << *j << std::endl ; // prints 7
std::cout << i.rc_->nlinks_ << std::endl ; // prints 2, i and j point to the same
{
mySmartPtr<int> k(j);
std::cout << i.rc_->nlinks_ << std::endl ; // prints 3, k points there two
}
std::cout << i.rc_->nlinks_ << std::endl ; // prints 2 , k gone out of scope
return 0;
}
Upvotes: 0
Reputation: 300129
You might be interested in libc++.
This is an implementation of the C++ Standard Library with a liberal license (MIT or BSD-like) so that you can freely pick stuff out of it.
All the stream handling is very complicated (lot of locale stuff), however the STL part (containers and algorithms) as well as part of the numeric stuff (apart from formatting) could work out of the box.
If you need streams, it's a little more involved.
Finally, your biggest issue might come from the exception handling. Note that the Standard Library is normally supposed to work with exceptions enabled (std::out_of_range
for example), and exception management is generally based on an external library (for example, see libunwind). Of course, since you reimplement your own library, you can choose to assert
instead of throwing.
I would seriously advise not using exceptions as it will be a major pain to make it work on all the devices you care about (it's a bit of a crippled C++ then, but you still get objects and templates).
Upvotes: 1