开发者

Visual c++ native memory management best practices

I am an old C# programmer and a C programmer (without dynamic memory allocation), but would like to learn a bit about Visual C++ programming. The question that bothers me is related to memory management in C++. In C#, garbage collector takes care of the memory management, but in C++, it is necessary that some rules are established regarding who is responsible for freeing the allocated memory. I have some typical scenarios from C#:

  1. Object is put in a container of some kind. Who is responsible for freeing the memory. What if several classes share the same object?

  2. Factory pattern. I like using a hierarchy of classes, where the parent class has a method for creating child objects?

  3. Is there a way to suggest to the calling method that t开发者_如何学Pythonhe returned object is in ownership of the callee/caller.

I would like to hear some good tips about this.


If you write your code correctly, you won't have to worry about this, at least not directly. There are library facilities available to you that handle memory management and other resource management for you, completely automatically, so that you don't have to.

C++ provides something far better than a garbage collector: it provides deterministic destruction of all objects, and that deterministic destruction can be used to automatically manage the lifetime of every resource, unlike garbage collection which (in many common implementations) only allows you to manage memory automatically and makes you manually manage all other resources that require deterministic cleanup.

If you dynamically allocate an object, use a smart pointer to manage its lifetime. If you don't need to share ownership, then you can use a std::unique_ptr, which allows you to transfer ownership from one owener to another. If you do need to share ownership, you can use a std::shared_ptr, which uses a reference counting technique to maintain shared ownership.

There are two important rules to keep in mind:

  • If you have to write delete in your C++ program, the code is almost certainly wrong. C++ provides automatic lifetime management for all resources, including memory, and you should take advantage of it. The only place delete should appear is in library code where resource-owning containers are implemented and potentially in rarer, low-level code.

  • Prefer to deal with objects, rather than pointers to objects, wherever possible. Wherever possible, you should avoid explicit dynamic allocation. C++ isn't like languages like C# and Java where most objects get created on the heap. It is often better in C++ to create objects on the stack (using automatic variables) and return them by value.

To answer your specific scenarios:

Object is put in a container of some kind. Who is responsible for freeing the memory. What if several classes share the same object?

You should prefer, wherever possible, to store the objects themselves in the container, not pointers to the objects. If you do for some reason need to store pointers to objects, you should use a container (e.g. a std::vector) of smart pointers. If the container has sole ownership of the dynamically allocated objects, you can use a std::vector<std::unique_ptr<T>>; if the container is going to share ownership of the objects, you can use a std::vector<std::shared_ptr<T>>.

Factory pattern. I like using a hierarchy of classes, where the parent class has a method for creating child objects?

This is no different from the previous scenario: if you have a tree, it's quite simple to use a std::vector<T> (or a std::vector<std::unique_ptr<T>> if you need dynamically allocated children) to own the children.

Is there a way to suggest to the calling method that the returned object is in ownership of the callee/caller.

If the object is solely owned by the callee (e.g. in a std::unique_ptr), then you can return that smart pointer; doing so will transfer ownership to the caller.

If there is shared ownership of the object (e.g. in a std::shared_ptr), then returning the smart pointer will make the caller one of the owners; the last owner to relinquish its ownership (by destroying or otherwise resetting its std::shared_ptr that owns the object) automatically destroys the object.


James's answer is correct. However, he doesn't mention the name of the technique that he is discussing. RAII is a very important concept for memory (and other resource) management in C++. RAII stands for Resource Acquisition Is Initialization. However, don't let the name confuse you because it's a little misleading.

Wikipedia is a good place to start reading: RAII on Wikipedia

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜