开发者

why would I forbid allocation in the heap?

开发者 https://www.devze.com 2023-01-12 01:07 出处:网络
I recently read a lot abou开发者_StackOverflow中文版t \"preventing heap allocation for a class\" (see this question).

I recently read a lot abou开发者_StackOverflow中文版t "preventing heap allocation for a class" (see this question).

I was able to understand "how", but now I can't figure out "why" someone would like to do that.

I guess there must be legitimate reasons for this, but I just can't figure them out.

In short: "Why may I want to forbid users from creating objects of my class in the heap ?"


Some classes make sense only if the objects are instantiated on the stack. For example, Boost scoped_ptr, or lock_guard.


Mainly because stack-allocated objects are automatically cleaned up when they go out of scope, thus removing a large class of bugs - namely memory allocation bugs.


I will go against the tide it seems (so I do expect downvotes, but please leave a comment to indicate the why).

I don't see any reason to forbid heap allocation, mainly because I don't like to second guess the potential uses of the classes I create.

As a design rule, I tend to put as few restrictions on the uses of my classes as possible. This means as few assumptions as possible. There is nothing as maddening as being unable to do what you wish simply because it was forbidden... for reasons either unknown or just plain wrong (denoting the superstitious/erroneous beliefs of the library writer).

Also, pragmatism teach that it's about impossible to actually prevent anything in C++. For example, some people have talked about guards --> what if I'd like to create a super class (which conveniently adds logging) ? Then I would put the guard class as an attribute, and even if its (the original class) new operator is private, my super class can be instantiated on the heap unless it somehow replicates the mechanism.

So, as for me, it's not a matter of why or how. I just don't fiddle with memory allocation schemes in library code, it's up to the user to use what's most convenient for her.


Usually it is a good idea to prevent the unexpected usage for the class. For example, consider Guard classes, that rely on RAII technique. They must be allocated on the stack and they do their job when they are going out of the scope. No one expect users to allocate guard objects in the heap, so it is explicitly forbidden.

Better explicit than implicit. Herb Shutter says that it must be hard to use your class incorrectly (allocating in the heap) and very easy to use it correctly (on the stack).


Stack allocation is faster(no searching for space needed).


For certain classes of very small objects - consider 3D points in a geometry engine - allocating these individually on the heap is a recipe for creating dangling pointers and introducing a vast amount of overhead - however, they are vitally necessary in a lot of calculations

So, a common mechanism is to use a flyweight pattern in objects that actually contain a collection of 3D points, like the description of some geometrical entity, and to allow their use on the heap as intermediate results of calculations.

Now, that said, extra special care needs to be taken to avoid needless copying of data between the flyweight implementation, e.g. ListOf3DPoints and the heap allocated 3D points that are being used for intermediate results.

In general, I've found a number of cases where I have coupled a flyweight pattern with heap allocation capabilities to achieve optimimum results - the flyweight provides persistent storage, the heap allocations let me perform item level manipulations without having to gen up another flyweight

0

精彩评论

暂无评论...
验证码 换一张
取 消