value_ptr
value_ptr is a so-called smart pointer. Really, it wants to be a smart reference, but you can't overload the . operator in C++, so -> had to do. Because the use of the -> operator makes it feel like you're using a pointer, it is named as such. I'm not really happy with the name. If you can think of a better one, answers on a post card please…
In short, when a value_ptr is copied, it performs a deep copy of the pointee. There are lots of existing smart pointers designed for this purpose, but I found them lacking in some respect. Most notably value_ptr has the following features:
- it is about as efficient as this kind of smart pointer can be…
- … while still being exception safe
- can interact with existing polymorphic hierarchies that provide a
clone()-like function (though the member function doesn’t have to be calledclone()) - provides conversions to/from value_ptrs referring to objects of related types e.g. a
value_ptr<derived>can be assigned to avalue_ptr<base> - does not allow slicing under any circumstances
- entirely non-intrusive
- support for custom allocators
- written in portable C++
Recent activity
Code
Clone the repository using mercurial:
> hg clone http://bitbucket.org/edd/value_ptr
Or get a zip file of the code.
Quick start
By default value_ptr will use the copy constructor of the type used for initialization:
#include <iostream>
#include <string>
#include <value_ptr.hpp>
class base
{
public:
base() : number(0) { }
virtual ~base() { }
virtual std::string name() const { return "base"; }
unsigned number;
};
class derived : public base
{
public:
virtual std::string name() const { return "derived"; }
};
int main()
{
derived d;
value_ptr<base> p(d); // note we don't pass a pointer, here.
// even though the type of p is value_ptr<base>, it really points to a derived
std::cout << p->name() << '\n'; // "derived"
value_ptr<base> p2(p);
p2->number = 42;
// copying a value_ptr copies the pointee via the copy constructor by default
std::cout << p2->number << '\n'; // 42
std::cout << p->number << '\n'; // 0
std::cout << p2->name() << '\n'; // "derived"
}
value_ptr can also use cloning functionality from your existing hierarchies and will prevent slicing by throwing an exception or triggering an assertion (your choice).
Further reading
- The
value_ptrwiki with more usage information - The motivation for
value_ptr.
Comments
[06/09/2010 at 14:59:41]
Have you considered trying to get this officially accepted into the boost library?
[10/09/2010 at 17:53:41]
The thought has crossed my mind, but this kind of thing appears with some regularity on the mailing list and there's disagreement on the best approach.
I'm happy to leave it alone, but feel free to champion it on the mailing list if you think it's worth it :)
[01/03/2011 at 21:29:39]
Yes, it is unfortunate and sane at the same time that we can't overload the . "operator". (But your blog is not about sanity (which I like) so it is just unfortunate.) Otherwise we could have perfect type erasure for hierarchies. However, have you though in overloading some other operator. like "|" or "*" or "&&" so it looks "less" like a pointer:
value_ptr<base> p(d);
//std::cout << p->name() << '\n';
std::cout << p|&base::name(); //not sure about the precedence of operators
maybe some combination of operators are better for precedence. (or Maybe this can't be used for virtual functions). -- Thanks,
[03/03/2011 at 23:19:24]
Re sanity: derived classes do it. I don't see why you couldn't have some other kind of proxy mechanism with the same name resolution rules (off the top of my head). But perhaps adding even more complexity to C++ isn't such a great idea :)
I think p|&base::name() would have to be (p|&base::name)() which is already looking a bit noisy to me. Even though I'd prefer to use a '.' over a '->', it's not too bad on the whole. Nice thought, though.
All original content copyright© Edd Dawson.
All source code appearing on this website that was written by Edd Dawson is made available under the terms of the Boost software license version 1.0 unless otherwise stated or implied by the license associated with the work from which the code is derived.

brian (rip-off)
[17/12/2007 at 16:45:00]
Impressive. I'll certainly consider using it next time I am programming and need something with its particular semantics.