>>10
and I don't know how magical automagic pointers work. I plan to learn C++ properly some day
No time like the present! I'm feeling helpful today, so here's a hand crafted zero-overhead non-transferable scoped smart pointer, written thirty seconds ago, just for you anon. Paste this sucker into your
void.h:
template <class T>
class scoped_ptr {
public:
explicit scoped_ptr(T* t) : t(t) {}
~scoped_ptr() {delete t;}
T* operator->() {return t;}
T& operator*() {return *t;}
private:
T* t;
scoped_ptr(const scoped_ptr<T>& other); // unimplemented; not allowed
T& operator=(const scoped_ptr<T>& other); // unimplemented; not allowed
};
This is the basis of a smart pointer. It's just a container that you put a pointer into; when the container is destroyed, it deletes the pointer. The idea is that you stack-allocate or field-allocate the container, so it automatically frees the pointer when it goes out of scope. That way the object can't leak if an exception goes by, if you return in the middle of a function, etc.
However it overloads
operator-> and
operator*, so you can use it like a regular pointer. It also disallows copy and assignment, so it can't be transferred. So to use it, instead of
Foo* foo(new Foo()), you write
scoped_ptr<Foo> foo(new Foo()) (notice I've stack-allocated scoped_ptr, which internally has a foo pointer).
Here's some test code, try it out:
#include <cstdio>
struct tester {
tester() {printf("constructor\n");}
~tester() {printf("destructor\n");}
void hello() {printf("hello\n");}
void world() {printf("world\n");}
};
int main(void) {
scoped_ptr<tester> obj(new tester());
obj->hello();
(*obj).world();
}
More typically though, smart pointers are transferable in special ways. For example shared_ptr internally keeps a reference count, so it knows how many copies you have about and frees the object when the last shared_ptr is destroyed. There's overhead for this though. auto_ptr and unique_ptr are transferable, and only one of them holds the real reference (it moves instead of copies); this is how you return smart pointers from functions. These get very complicated in order to implicitly convert smart pointer types based on the inheritance tree of their contained pointer. And of course you need a special smart pointer for arrays, because you have to use delete[] instead of delete.