OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Scopers help you manage ownership of a pointer, helping you easily manage a | 5 // Scopers help you manage ownership of a pointer, helping you easily manage a |
6 // pointer within a scope, and automatically destroying the pointer at the end | 6 // pointer within a scope, and automatically destroying the pointer at the end |
7 // of a scope. There are two main classes you will use, which correspond to the | 7 // of a scope. There are two main classes you will use, which correspond to the |
8 // operators new/delete and new[]/delete[]. | 8 // operators new/delete and new[]/delete[]. |
9 // | 9 // |
10 // Example usage (scoped_ptr<T>): | 10 // Example usage (scoped_ptr<T>): |
(...skipping 19 matching lines...) Expand all Loading... |
30 // { | 30 // { |
31 // scoped_ptr<Foo[]> foo(new Foo[100]); | 31 // scoped_ptr<Foo[]> foo(new Foo[100]); |
32 // foo.get()->Method(); // Foo::Method on the 0th element. | 32 // foo.get()->Method(); // Foo::Method on the 0th element. |
33 // foo[10].Method(); // Foo::Method on the 10th element. | 33 // foo[10].Method(); // Foo::Method on the 10th element. |
34 // } | 34 // } |
35 // | 35 // |
36 // These scopers also implement part of the functionality of C++11 unique_ptr | 36 // These scopers also implement part of the functionality of C++11 unique_ptr |
37 // in that they are "movable but not copyable." You can use the scopers in | 37 // in that they are "movable but not copyable." You can use the scopers in |
38 // the parameter and return types of functions to signify ownership transfer | 38 // the parameter and return types of functions to signify ownership transfer |
39 // in to and out of a function. When calling a function that has a scoper | 39 // in to and out of a function. When calling a function that has a scoper |
40 // as the argument type, it must be called with the result of an analogous | 40 // as the argument type, it must be called with an rvalue of a scoper, which |
41 // scoper's Pass() function or another function that generates a temporary; | 41 // can be created by using std::move(), or the result of another function that |
42 // passing by copy will NOT work. Here is an example using scoped_ptr: | 42 // generates a temporary; passing by copy will NOT work. Here is an example |
| 43 // using scoped_ptr: |
43 // | 44 // |
44 // void TakesOwnership(scoped_ptr<Foo> arg) { | 45 // void TakesOwnership(scoped_ptr<Foo> arg) { |
45 // // Do something with arg | 46 // // Do something with arg. |
46 // } | 47 // } |
47 // scoped_ptr<Foo> CreateFoo() { | 48 // scoped_ptr<Foo> CreateFoo() { |
48 // // No need for calling Pass() because we are constructing a temporary | 49 // // No need for calling std::move() for returning a move-only value, or |
49 // // for the return value. | 50 // // when you already have an rvalue as we do here. |
50 // return scoped_ptr<Foo>(new Foo("new")); | 51 // return scoped_ptr<Foo>(new Foo("new")); |
51 // } | 52 // } |
52 // scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) { | 53 // scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) { |
53 // return arg.Pass(); | 54 // return arg; |
54 // } | 55 // } |
55 // | 56 // |
56 // { | 57 // { |
57 // scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay"). | 58 // scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay"). |
58 // TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay"). | 59 // TakesOwnership(std::move(ptr)); // ptr no longer owns Foo("yay"). |
59 // scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo. | 60 // scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo. |
60 // scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2. | 61 // scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2. |
61 // PassThru(ptr2.Pass()); // ptr2 is correspondingly nullptr. | 62 // PassThru(std::move(ptr2)); // ptr2 is correspondingly nullptr. |
62 // } | 63 // } |
63 // | 64 // |
64 // Notice that if you do not call Pass() when returning from PassThru(), or | 65 // Notice that if you do not call std::move() when returning from PassThru(), or |
65 // when invoking TakesOwnership(), the code will not compile because scopers | 66 // when invoking TakesOwnership(), the code will not compile because scopers |
66 // are not copyable; they only implement move semantics which require calling | 67 // are not copyable; they only implement move semantics which require calling |
67 // the Pass() function to signify a destructive transfer of state. CreateFoo() | 68 // the std::move() function to signify a destructive transfer of state. |
68 // is different though because we are constructing a temporary on the return | 69 // CreateFoo() is different though because we are constructing a temporary on |
69 // line and thus can avoid needing to call Pass(). | 70 // the return line and thus can avoid needing to call std::move(). |
70 // | 71 // |
71 // Pass() properly handles upcast in initialization, i.e. you can use a | 72 // The conversion move-constructor properly handles upcast in initialization, |
72 // scoped_ptr<Child> to initialize a scoped_ptr<Parent>: | 73 // i.e. you can use a scoped_ptr<Child> to initialize a scoped_ptr<Parent>: |
73 // | 74 // |
74 // scoped_ptr<Foo> foo(new Foo()); | 75 // scoped_ptr<Foo> foo(new Foo()); |
75 // scoped_ptr<FooParent> parent(foo.Pass()); | 76 // scoped_ptr<FooParent> parent(std::move(foo)); |
76 | 77 |
77 #ifndef BASE_MEMORY_SCOPED_PTR_H_ | 78 #ifndef BASE_MEMORY_SCOPED_PTR_H_ |
78 #define BASE_MEMORY_SCOPED_PTR_H_ | 79 #define BASE_MEMORY_SCOPED_PTR_H_ |
79 | 80 |
80 // This is an implementation designed to match the anticipated future TR2 | 81 // This is an implementation designed to match the anticipated future TR2 |
81 // implementation of the scoped_ptr class. | 82 // implementation of the scoped_ptr class. |
82 | 83 |
83 #include <assert.h> | 84 #include <assert.h> |
84 #include <stddef.h> | 85 #include <stddef.h> |
85 #include <stdlib.h> | 86 #include <stdlib.h> |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 scoped_ptr<T> make_scoped_ptr(T* ptr) { | 596 scoped_ptr<T> make_scoped_ptr(T* ptr) { |
596 return scoped_ptr<T>(ptr); | 597 return scoped_ptr<T>(ptr); |
597 } | 598 } |
598 | 599 |
599 template <typename T> | 600 template <typename T> |
600 std::ostream& operator<<(std::ostream& out, const scoped_ptr<T>& p) { | 601 std::ostream& operator<<(std::ostream& out, const scoped_ptr<T>& p) { |
601 return out << p.get(); | 602 return out << p.get(); |
602 } | 603 } |
603 | 604 |
604 #endif // BASE_MEMORY_SCOPED_PTR_H_ | 605 #endif // BASE_MEMORY_SCOPED_PTR_H_ |
OLD | NEW |