Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Irrational fear of C++

Name: Anonymous 2010-01-22 14:25

I have an irrational fear of C++. More than once have I swayed away from useful libraries because all they offered was a C++ API. I have perused several books on C++, but they have done nothing but strengthened the feeling that C++ is too complex to reasonably handle. What to do?

Name: Anonymous 2010-01-22 18:54

>>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.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List