Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualHodgman

Posted 16 December 2012 - 05:39 AM

An object that maintains the scope of the variables, and calls their destructors for them? Very nice.

This is the whole point of RAII, a key idiom in C++. I wish I could take credit for this "Scope" class, which associates multiple objects' lifetimes with a single "RAII object", but I have to credit DICE for that idea Posted Image
It's kind of similar to an array of std::unique_ptr's, I guess.

Reading through, I assume that it means that you only ever allocate objects in order, and the lifetime of your objects follow a strict schedule. Do you ever have a need to allocate an object whose lifetime is not decided by the place where it is allocated?

When I first read through DICE's presentation, I did think this would be a bigger issue (because I was used to writing "typical" C++ at the time), but now I've built an engine from the ground up using these kinds of allocators, and the majority of the time it has worked out!
For cases where it's not suitable, I'll often allocate a fixed size pool (using eiNew) and then objects can be allocated within the pool with varying lifetimes (as long as none of the objects need to live longer than the pool itself).

Sometimes lifetimes are too hard to reason about, in which case, reference counting via std::shared_ptr can be a good solution, however, I find these cases to be quite rare.
My engine has interoperability with a Lua VM, which has a garbage collector. Usually if I'm writing code with unpredictable lifetime rules, then it happens to be Lua code, and I don't have to worry about it Posted Image

Also, sometimes simply using malloc/free can be the simplest solution, and KISS is a good principle! When I use malloc in C++, I try to use it via a RAII wrapper, which automatically calls free for me.
Going off on a tangent -- the NonCopyable class in my code that I've linked to, is a feature I picked up from boost (much of which is now in std::). It's a neat trick that stops people from accidentally using the assignment-operator or copy-constructor on classes that shouldn't be cloneable.
e.g. If I was to make my ScopedMalloc class compliant with the rule of three, then it would need an assignment operator and a copy-constructor, which logically would use memcpy to clone the allocation... However, this doesn't seem like a feature I'd ever want to use, so instead I inherit from NonCopyable, so if anyone every tries to clone a ScopedMalloc, then they'll get a compile error instead. If they actually want to clone their allocation, they can write that manually (and more importantly, I'm still complying with the rule-of-three now).

#1Hodgman

Posted 16 December 2012 - 05:30 AM

An object that maintains the scope of the variables, and calls their destructors for them? Very nice.

This is the whole point of RAII, a key idiom in C++. I wish I could take credit for this "Scope" class, which associates multiple objects' lifetimes with a single "RAII object", but I have to credit DICE for that idea Posted Image
It's kind of similar to an array of std::unique_ptr's, I guess.

Reading through, I assume that it means that you only ever allocate objects in order, and the lifetime of your objects follow a strict schedule. Do you ever have a need to allocate an object whose lifetime is not decided by the place where it is allocated?

When I first read through DICE's presentation, I did think this would be a bigger issue (because I was used to writing "typical" C++ at the time), but now I've built an engine from the ground up using these kinds of allocators, and the majority of the time it has worked out!
For cases where it's not suitable, I'll often allocate a fixed size pool (using eiNew) and then objects can be allocated within the pool with varying lifetimes (as long as none of the objects need to live longer than the pool itself).

Sometimes lifetimes are too hard to reason about, in which case, reference counting via std::shared_ptr can be a good solution, however, I find these cases to be quite rare.
My engine has interoperability with a Lua VM, which has a garbage collector. Usually if I'm writing code with unpredictable lifetime rules, then it happens to be Lua code, and I don't have to worry about it Posted Image

Also, sometimes simply using malloc/free can be the simplest solution, and KISS is a good principle! When I use malloc in C++, I try to use it via a RAII wrapper, which automatically calls free for me.
Going off on a tangent -- the NonCopyable class in my code that I've linked to, is a feature I picked up from boost (much of which is now in std::). It's a neat trick that stops people from accidentally using the assignment-operator or copy-constructor on classes that shouldn't be cloneable.

PARTNERS