{"id":5153,"date":"2008-02-22T13:53:00","date_gmt":"2008-02-22T13:53:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2008\/02\/22\/tr1-slide-decks\/"},"modified":"2019-02-18T18:54:11","modified_gmt":"2019-02-18T18:54:11","slug":"tr1-slide-decks","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/tr1-slide-decks\/","title":{"rendered":"TR1 Slide Decks"},"content":{"rendered":"<p><font face=\"Verdana\" size=\"3\"><\/p>\n<p class=\"MsoNormal\"><span>Hi, I&#8217;m Stephan, the Visual C++ Libraries Developer working on TR1.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Recently, I gave 3 presentations within Microsoft about the most novel components of TR1: shared_ptr, regex, and the additions to &lt;functional&gt; (including mem_fn(), bind(), and tr1::function).&nbsp; These presentations explained where to use, how to use, and how to avoid misusing these components, with plenty of examples.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p><span><\/p>\n<p class=\"MsoNormal\"><span>Attached at the end of this post is a ZIP of the slide decks for each of the presentations, in PowerPoint 2007 format.<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Each slide deck mostly stands alone, although the &#8220;shared_ptr To Noncopyable&#8221; and &#8220;shared_ptr To Polymorphic&#8221; examples require some context and additional explanation:<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>The &#8220;shared_ptr To Noncopyable&#8221; example demonstrates how to create a container of noncopyable resource managers.&nbsp; A resource is something that must be acquired from the system and then released afterwards.&nbsp; The most common resource is memory (acquired in C++ with new, and released with delete), but there are many non-memory resources, such as files, sockets, textures, fonts, and so forth.&nbsp; A resource manager is an object that encapsulates a resource, controlling its lifetime and permitting access to it.&nbsp; Resource managers acquire resources in their constructors, and release resources in their destructors (this is the somewhat-mysteriously-named RAII principle: Resource Acquisition Is Initialization, implying RRID: Resource Release Is Destruction).&nbsp; std::vector is an example of a resource manager for memory, while std::ifstream is an example of a resource manager for files.&nbsp; Memory resource managers are usually copyable (and assignable); chunks of memory can easily be copied and assigned.&nbsp; But non-memory resource managers are usually noncopyable (and nonassignable); either their underlying resources can&#8217;t be copied without additional information (e.g. copying a file requires a new name), or copying them is a relatively expensive operation (e.g. textures consume precious video card memory, etc.).&nbsp; So, it&#8217;s best to prohibit copy construction and copy assignment of non-memory resource managers.&nbsp; This requires programmers to explicitly copy the underlying resources when that&#8217;s desired.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>The problem here is that STL (and TR1) containers require ordinary value types.&nbsp; An ordinary value type is &#8220;something that behaves like an int&#8221;; ints are copyable and assignable.&nbsp; vectors copy their contained elements when undergoing reallocation, and so forth.&nbsp; You can&#8217;t have a vector&lt;ifstream&gt; because ifstream is noncopyable.&nbsp; But sometimes, that&#8217;s exactly what you want.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>In this example (admittedly somewhat contrived), I&#8217;m writing a program to interleave text files.&nbsp; The user will have an arbitrary number of text files, and will provide the names of the files to the program.&nbsp; Then, the program will have to loop through the files in order, printing out the first line of each file, then the second line, and so forth.&nbsp; When a text file runs out of lines (they can have different numbers of lines), the program has to start skipping that file.&nbsp; When all the lines from all the files have been printed, the program has to stop.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Now, I could write this by reading each file into a vector&lt;string&gt; (storing each line), and building up a vector&lt;vector&lt;string&gt; &gt; (storing each file), and then looping through that.&nbsp; But that would require reading everything into memory.&nbsp; Suppose I don&#8217;t want to do that.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Well, if I could use a vector&lt;ifstream&gt;, I could repeatedly loop through the vector, reading one line from each file in turn.&nbsp; When a file ran out of lines, I could remove it from the vector.&nbsp; But ifstream is noncopyable.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>To solve this, I can use shared_ptr.&nbsp; shared_ptr can be used as a handle to a noncopyable object; the shared_ptr itself is copyable and assignable.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Slide 1\/3 of the example shows the contents of 3 text files.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Slide 2\/3 shows the code.&nbsp; To fit the code onto a single slide, I use a queue&lt;shared_ptr&lt;ifstream&gt; &gt;.&nbsp; I begin by reading filenames from cin (with the for-loop).&nbsp; From each filename, I new up an ifstream, held by shared_ptr, and push it into the queue.&nbsp; At the end of this for-loop, the queue contains shared_ptrs to the files mentioned by the user in order.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Then, I loop through the queue (with the while-loop) as long as it contains files to process.&nbsp; I attempt to read a line from the file at the front of the queue (this is the next file to process).&nbsp; If that&#8217;s successful (the file still contains lines), I print it out.&nbsp; I want to keep working on that file, so I push() a copy of the shared_ptr to this file (q.front()), to the back of the queue.&nbsp; Then I pop() the front of the queue.&nbsp; (At this point, particularly attentive readers should ask whether q.push(q.front()) raises the specter of iterator invalidation; the answer is that it does not.&nbsp; I would have avoided this in the interests of clarity, but it would have taken more lines.)&nbsp; If I wasn&#8217;t able to read a line from the file, then it&#8217;s empty, so I simply want to pop it from the front of the queue.&nbsp; Then I continue with the loop.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Slide 3\/3 shows the filenames being entered, and the program&#8217;s output.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>The &#8220;shared_ptr To Polymorphic&#8221; example demonstrates how to create a container of polymorphic objects (i.e. classes with virtual functions).&nbsp; Polymorphic objects should always be noncopyable, because of the danger of slicing.&nbsp; Inheritance means substitutability; a Derived object has to be usable wherever a Base object would be usable.&nbsp; However, copying presents a problem.&nbsp; If Base is copyable, then you can copy from a Base to a Base.&nbsp; But substitutability then implies that you can copy from a Derived (which is a Base) to a Base.&nbsp; This &#8220;slices&#8221; off any Derived behavior and state, which is almost always undesirable.&nbsp; Therefore, copy construction and copy assignment of polymorphic base classes should be prohibited.&nbsp; (You should provide a virtual clone() function if you need to copy polymorphic objects safely.)<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>If Base is noncopyable, you can&#8217;t have a vector&lt;Base&gt;.&nbsp; You could try to use a vector&lt;Base *&gt;, newing up Derived objects and storing pointers to them, but that would be highly likely to leak, especially in the presence of exceptions.&nbsp; As with resource managers, shared_ptr allows us to manipulate noncopyable objects with copyable handles.&nbsp; vector&lt;shared_ptr&lt;Base&gt; &gt; is a powerful construct that can be used in many situations.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>In this example (even more contrived; you can mentally substitute your favorite Base and Derived classes), I have a polymorphic base class Animal.&nbsp; Therefore, it has a virtual destructor, no copy constructor, and no copy assignment operator.&nbsp; It stores a string m_name (the name of the Animal), and has an explicit constructor taking that name.&nbsp; Animal uses the Non-Virtual Inheritance idiom, so it has a public, non-virtual member function named noise(), which returns &#8220;&lt;name&gt; says &lt;something&gt;&#8221;.&nbsp; The &#8220;something&#8221; is customizable by derived classes, through the private pure virtual member function noise_impl().&nbsp; (Yes, private virtual member functions can be overridden; the difference is that derived classes cannot call the base implementation, whereas they could if the base implementation were protected.&nbsp; As noise_impl() is pure, there is no base implementation, so the difference is theoretical &#8211; but I prefer to lock down access control unless I need looser control.)<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Slide 2\/4 shows three derived classes, Cat, Dog, and Pig, identical in structure except for what their noise_impl()s return.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Slide 3\/4 constructs a vector&lt;shared_ptr&lt;Animal&gt; &gt;, which is then filled with a Cat, Dog, and Pig.&nbsp; Then I print out the noises that each Animal makes.&nbsp; I use the STL algorithm transform() on the vector, printing strings to cout separated by newlines.&nbsp; mem_fn(&amp;Animal::noise) uses tr1::mem_fn() to adapt a pointer-to-member-function (&amp;Animal::noise) to a function-object (what transform() wants).<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Slide 4\/4 shows the output, demonstrating that the virtual function calls worked as usual.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>The point of these two examples is that shared_ptr is useful for much more than sharing and exception safety.&nbsp; shared_ptr allows you to use the STL in more situations, by wrapping noncopyable objects in copyable clothing.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>If you have any questions, I&#8217;ll be happy to answer them in the Comments!<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Stephan T. Lavavej<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p><\/font><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/TR1%20Presentations.zip\">TR1 Presentations.zip<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi, I&#8217;m Stephan, the Visual C++ Libraries Developer working on TR1. &nbsp; Recently, I gave 3 presentations within Microsoft about the most novel components of TR1: shared_ptr, regex, and the additions to &lt;functional&gt; (including mem_fn(), bind(), and tr1::function).&nbsp; These presentations explained where to use, how to use, and how to avoid misusing these components, with [&hellip;]<\/p>\n","protected":false},"author":289,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-5153","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus"],"acf":[],"blog_post_summary":"<p>Hi, I&#8217;m Stephan, the Visual C++ Libraries Developer working on TR1. &nbsp; Recently, I gave 3 presentations within Microsoft about the most novel components of TR1: shared_ptr, regex, and the additions to &lt;functional&gt; (including mem_fn(), bind(), and tr1::function).&nbsp; These presentations explained where to use, how to use, and how to avoid misusing these components, with [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/5153","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/289"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=5153"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/5153\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=5153"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=5153"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=5153"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}