16

What does it mean to express "Ownership of resources"? Is it the same as having ownership of pointers? For example in this answer, the expression was used "PODs cannot express ownership of pointers or resources". Classes that involve dynamic memory management, do they express ownership of pointers or resources?

  • You might want to read up on [RAII](https://stackoverflow.com/questions/2321511/what-is-meant-by-resource-acquisition-is-initialization-raii), which stands for Resource Acquisition Is Initialization. – MSalters Feb 28 '18 at 08:39
  • "pointers or resources", what are resources? – KcFnMi Feb 11 '23 at 12:50
  • @KcFnMi A resource in this context could be a file handle or a mutex or a database transaction or a reservation from a flight reservation system. There are many more. They have in common that you akquire them and later release them. RAII does this automatically, even with exceptions involved, and thus prevents resource leaks. – Sebastian Feb 12 '23 at 08:25
  • Got it! Appreciate if you could also clarify what is a handle? When I read handle I use to replace it by pointer in my mind, so I can understand it. Just not totally sure about it. – KcFnMi Feb 12 '23 at 08:48
  • @KcFnMi For memory a handle typically is a pointer, for other more abstract resources, a handle can be a file number, a session id or session key. Generally a handle allows you to access the resource (like a door handle), often (depending on the resource) multiple times as long as the handle is valid. In C++ the life time management of resources is typically solved with RAII. The resource is akquired by constructing an object and released by destroying the object. The object is either a local (=automatic) variable or a member variable of another object. – Sebastian Feb 12 '23 at 13:25
  • The object itself is used as resource handle, as parameter when calling other functions, or directly provides member functions for accessing the resource or is used for constructing another object providing access and stored therein. – Sebastian Feb 12 '23 at 13:26

1 Answers1

30

I don't think there is a universally accepted, 100% accurate and always-applicable definition, but the most useful definition of ownership I've encountered in the context of C++ (and programming in general) is responsibility for cleanup. That is, an owner of a resource is the one who's responsible for correct cleanup of that resource.

What "resource" and "cleanup" mean depends on context. When the resource is memory dynamically allocated via new, cleanup is calling delete. When the resource is a file descriptor, cleanup is closing it. And so on.

That's why Plain Old Data cannot express ownership: a POD class must have a no-op destructor, and thus cannot perform any automatic cleanup.

Compare int *, std::unique_ptr<int>, and std::shared_ptr<int>. All these types are "a pointer to an int". But the first one does not represent ownership — you can do anything you want with it, and you can happily use it in ways which lead to memory leaks or double-frees.

std::unique_ptr<int> represents the simplest form of ownership: it says "I am the sole owner of the resource (= the dynamically allocated int). When I get destroyed, I clean it up correctly." It is designed not to offer a sane way of violating the ownership semantics (e.g. it's noncopyable).

std::shared_ptr<int> represents a more complex form of ownership: "I am one of a group of friends who are collectively responsible for the resource. The last of us to get destroyed will clean it up." Again, there are a few hoops to jump through before you can violate the semantics.

Quentin
  • 62,093
  • 7
  • 131
  • 191
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • Thanks a lot for such a great answer. I have a few questions: <1> What is a `no-op destructor`? (you said *"... a POD class must have a no-op destructor ..."*) <2> Could you please elaborate on or share useful links on *"It is designed not to offer a sane way of violating the ownership semantics (e.g. it's noncopyable)."*? – Milan Oct 19 '21 at 16:03
  • 1
    @Milan 1) The standardese for that is *trivial destructor*: in plain terms, it's not user provided and doesn't do anything (all members and bases have trivial destructors too). 2) Sorry, nothing on hand. Basically, the interface of `std::unique_ptr` is designed so that you have to jump through a few hoops before you can misuse it (but it can be done, of course). – Angew is no longer proud of SO Oct 20 '21 at 07:14
  • Thank you Angew. Sorry but two more things: 1. by *standardese*, you meant this https://github.com/standardese/standardese right? 2. Thanks for clarifying on `std::unique_ptr` interface. Whenever you come across some relevant resources for that, please share them here. Would greatly appreciate that! – Milan Oct 20 '21 at 18:38
  • 2
    @Milan No, I didn't mean that at all. I meant "standardese" as "the language used by the C++ standard", analogously to the word "legalese" as "the usually convoluted formal language used in licenses or contracts." – Angew is no longer proud of SO Oct 21 '21 at 06:24