1

In the book "C++ Coding Standards. 101 Rules, Guidelines, and Best Practices" by Herb Sutter and Andrei Alexandrescu in Rule 52, the final quote is:

"In rare cases, classes that have members of strange types (e.g., references, std::auto_ptrs) are an exception because they have peculiar copy semantics. In a class holding a reference or an auto_ptr, you likely need to write the copy constructor and the assignment operator, but the default destructor already does the right thing. (Note that using a reference or auto_ptr member is almost always wrong.)"

It is clear why using references as members is not a good idea (answer to this question is in this post: Should I prefer pointers or references in member data?)

  1. With regard to a modern C++, does it also mean that using unique_ptr as a class member is usually a bad thing? Or was it a problem only of auto_ptr and missing move semantics maybe?
  2. Should shared_ptr be used for a polymorphic behavior then?

Thanks in advance!

Roman2452809
  • 378
  • 1
  • 2
  • 17
  • 3
    As `unique_ptr` is not copyable, it doesn't have a strange copy semantic, contrary to `auto_ptr`. – Jarod42 Jul 01 '19 at 10:10
  • 5
    Going from advice about `auto_ptr` to conclusions about `unique_ptr` is quite a leap. – StoryTeller - Unslander Monica Jul 01 '19 at 10:11
  • i think this should be read as "dont use reference members unless you need them to be a reference" instead of "never use reference members", though I might misunderstand the quote, I am also in disagreement of other uses of the "almost always" phrase – 463035818_is_not_an_ai Jul 01 '19 at 10:18
  • 1
    `auto_ptr` was a hack, and it reflected a naive view of how ownership worked. The lessons we learned from it are incorporated in the newer types of shared pointers, so guidelines about how to use `auto_ptr` do not apply to anything else. May it rest in peace. – Pete Becker Jul 01 '19 at 13:01
  • @PeteBecker Also rvalue reference did not exist when `auto_ptr` was designed so nobody can blame lib ppl for not having proper core language tools – curiousguy Jul 04 '19 at 18:41

2 Answers2

3
  1. With regard to a modern C++, does it also mean that using unique_ptr as a class member is usually a bad thing?

It doesn't meant that, and use of unique pointers isn't a bad thing.

Or was it a problem only of auto_ptr and missing move semantics maybe?

The main problem is that copying of auto_ptr transfers ownership of the pointed resource. This is what the author refers to with "peculiar copy semantics".

Given that const auto_ptr cannot be copied, it is not nearly as dangerous as a non-const one is. It had niche uses, but uses of non-copyable types are quite limited pre-C++11.

Unique pointer doesn't have peculiar copy semantics. In fact, unique pointers are not copyable at all. This is not as much of a problem in C++11 where a type can be movable. Unique pointers cover all use cases where auto_ptr was usable, as well as others where auto_ptr was treacherous.

  1. Should shared_ptr be used for a polymorphic behavior then?

Shared pointer can be used, but it is not necessary.

P.S. auto_ptr was deprecated in C++11, and removed from the standard library completely in C++17.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Copying a non const `auto_ptr`. Constant objects (`auto_ptr` or classes containing them) couldn't be copied. Core C++ officially supports calling a function taking a NON const reference a copy ctor. – curiousguy Jul 04 '19 at 18:47
1

Using a unique_ptr member is not a bad practice since the class it's a member of is the owner of the allocated object. However, it will complicate how the class containing it is handled since it prevents the class from being copyable. So, if the class contains any other non-trivial members, then you'll have to write a move constructor, move assignment operator and a destructor for your class.

On the contrary, I'd consider using shared_ptr as class members a bad practice, since it doesn't imply any kind of ownership and causes a non-deterministic object life-time in your code since you have no idea when the last instance of the object held by shared_ptr is freed.

rashmatash
  • 1,699
  • 13
  • 23
  • 1
    `I'd consider using shared_ptr as class members a bad practice, since it doesn't imply any kind of ownership` On the contrary, shared pointer implies a *shared ownership*, as the name suggests. – eerorika Jul 01 '19 at 10:17
  • Agreed! What I meant was that no one in particular is in charge of managing that object's life-time, which I'm not comfortable with in general (but that's also a matter of style and taste). – rashmatash Jul 01 '19 at 10:19
  • What do you mean by non-deterministic? – curiousguy Jul 04 '19 at 18:42
  • @eerorika What the hell is shared ownership? Who owns the resource? – curiousguy Jul 04 '19 at 18:42
  • @curiousguy All of the shared pointers pointing to that resource share the ownership among each other. In unique ownership, the owner is responsible for releasing the resource. In shared ownership, there are potentially multiple owners, and the last owner to be destroyed is responsible for releasing the resource. – eerorika Jul 04 '19 at 18:47
  • @eerorika So ownership is divided? Who *owns* the resource? How is that ownership? – curiousguy Jul 04 '19 at 18:49
  • @curiousguy `So ownership is divided?` The word I'd use is *shared*, but sure. `Who owns the resource?` The set of shared pointers that point to the resource. `How is that ownership?` I'm not quite sure what you're asking. The shared pointers are the owner because they are responsible for the release - and vice versa. Those are two ways to express the same concept. – eerorika Jul 04 '19 at 18:58
  • @eerorika The legal concept of ownership means that you can use and destroy the object. Shared ownership implies that you don't know what uses are valid (can you change the value? how?) and that you can't destroy it. Also, you can't transfer proper (non shared) ownership (no `release`). So it isn't ownership at all. – curiousguy Jul 05 '19 at 01:55
  • @curiousguy Where is this *legal* concept of ownership of yours formally specified? Are you implying that smart pointers do not implement ownership semantics or something else? (I don't quite see what your point is). Ownership can be transferred from one unique pointer to another, or it can be transferred to from unique pointer to a shared pointer. You cannot transfer shared ownership back to unique ownership. – eerorika Jul 05 '19 at 02:35
  • @eerorika Ownership may be the most studied and well understood legal concept. Shared ownership is not ownership, as it does not have the needed properties: an owner should be able to destroy the owned resource, or transfer the ownership; neither is supported. `shared_ptr` does not model ownership, it models a contract of "keep alive until" (for lack of better term). – curiousguy Jul 05 '19 at 05:25
  • @curiousguy `Ownership may be the most studied and well understood legal concept.` I'm asking for a citation. `an owner should be able to destroy the owned resource, or transfer the ownership` Those are properties of unique ownership. Indeed, shared pointer does not have unique ownership semantics. Shared ownership is different from unique ownership. `(for lack of better term)` There's a term for it, used for example in the c++ standard: It's called shared ownership. AFAIK, it's fairly established term. – eerorika Jul 05 '19 at 10:33
  • @eerorika And it's a bad term and w/o precedent IMO. Shared ownership simply is a contradiction. It doesn't have the attributes of what ppl normally call ownership: if you are part owner, you don't own anything. You only have a contract with the only owner (the control block) that the resource will not go away too early. You may accept the term ownership for such a contract but I don't. You can't even know whether you are the only owner, with the (very bad) decision to drop `unique()`, instead of fixing it! – curiousguy Jul 05 '19 at 15:18