Changeset 54658


Ignore:
Timestamp:
Jul 4, 2009, 11:20:41 PM (9 years ago)
Author:
cschladetsch
Message:

updated docs

Location:
sandbox/cloneable
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • sandbox/cloneable/boost/cloneable/abstract_base.hpp

    r54656 r54658  
    5454                                        return copy;
    5555                                return copy_construct(alloc);
     56                        }
     57
     58                        /// MUTABLE
     59                        virtual this_type *make_copy(abstract_allocator &) { return 0; }
     60
     61                        /// MUTABLE
     62                        this_type *clone(abstract_allocator &alloc)
     63                        {
     64                                if (this_type *copy = make_copy(alloc))
     65                                        return copy;
     66                                const this_type *const_this = const_cast<const this_type *>(this);
     67                                if (this_type *copy = const_this->make_copy(alloc))
     68                                        return copy;
     69                                return const_this->copy_construct(alloc);
    5670                        }
    5771
  • sandbox/cloneable/libs/cloneable/doc/cloneable.qbk

    r54657 r54658  
    145145``
    146146
    147 Note that we pass references to these functions rather than pointers, and these functions work for ['Cloneable] types and generally.
     147__note__ we pass references to these functions rather than pointers, and these functions work for ['Cloneable] types and generally.
    148148We can also pass an allocator to these functions, but more on custom allocation later.
    149149
     
    176176``
    177177
    178 Note that `Animal` doesn't have to derive from anything, or have any special members or methods.
     178__note__ `Animal` doesn't have to derive from anything, or have any special members or methods.
    179179Now let's use our base class to create a simple type hierarchy:
    180180
     
    218218``
    219219
    220 Note that the `clone()` method returns
     220__note__ the `clone()` method returns
    221221a pointer to the base class of the type hierarchy - in this case, `Animal`.
    222222We had to use a dynamic cast to down-cast to our derived type.
     
    251251``
    252252
    253 `Dog` is just like a cat, but different. `Labrador` is the first example we have seen
     253`Dog` is just like a cat, but different :-). `Labrador` is the first example we have seen
    254254that uses multiple inheritance. In this case, we are saying that a Labrador is-a Dog,
    255255and is Cloneable as either a Dog or a Labrador. Using these types:
     
    429429    T2 *t2 = new T2();
    430430   
    431     assert(can_clone_as<W>(*t2));
    432     assert(can_clone_as<T0>(*t2));
    433     assert(can_clone_as<T1>(*t2));
    434     assert(can_clone_as<T2>(*t2));
    435    
    436     assert(can_create_as<W>(*t2));
    437     assert(can_create_as<T0>(*t2));
    438     assert(can_create_as<T1>(*t2));
    439     assert(can_create_as<T2>(*t2));
     431    assert(t2->can_clone_as<W>());
     432    assert(t2->can_clone_as<T0>());
     433    assert(t2->can_clone_as<T1>());
     434    assert(t2->can_clone_as<T2>());
     435   
     436    assert(t2->can_create_as<W>());
     437    assert(t2->can_create_as<T0>());
     438    assert(t2->can_create_as<T1>());
     439    assert(t2->can_create_as<T2>());
    440440   
    441441    // clone sub-objects
     
    455455``
    456456
    457 Note that if a sub-type `S` in type `T` is not default-constructabe, an exception of type
     457__alert__ if a sub-type `S` in type `T` is not default-constructabe, an exception of type
    458458`no_default_construction` will be thrown if you attempt to default-create a new `S` instance
    459459from a `T` instance.
     
    484484``
    485485
    486 Please ensure that you override the `make_copy()` method correctly. It must return
    487 a type that is co-variant with the base you used for the derived type, and must be
    488 `const`. If you make a mistake on the return type, the compiler will complain. But
    489 if you forget to make the method const, it will not be invoked when needed and there
    490 will be no warning or error.
    491 
    492 This example uses the heap to make clones; we will next see how to make
    493 clones using any standard-compliant allocator type.
     486Please ensure that you override the `make_copy() const` method correctly. It must return
     487a type that is co-variant with the base you used for the derived type, and should be
     488`const`. If you make a mistake on the return type, the compiler will complain.
     489There is a non-const `make_copy()` method as well. This will be invoked on a non-const
     490original, then the const `make_copy() const` will be attempted before finally using
     491the `copy_construct() const` method. To summarise:
     492
     493* Attempting to make a copy of a non-const original will invoke `make_copy()`
     494* If this fails or is not over-ridden, then the `make_copy() const` method is invoked.
     495* If this fails is or not over-ridden, then `copy_construct() const` is invoked.
     496
     497This provides a means for clones to be made that alter the original, if you need
     498to do that. For `const` originals, the process starts from step 2. All of these
     499methods are over-loaded with a similar method that takes an `abstract_allocator` argument.
     500
     501Which is a nice segue into the next section. This example used the heap to make clones;
     502we will next see how to make clones using any standard-compliant allocator type.
    494503
    495504[endsect]
     
    503512When making a new object, sub-object, clone or sub-clone, the underlying `abstract_base`
    504513is given a reference to an `abstract_allocator`. This is
    505 an interface (containing only pure virtual methods) that is used to expose a specialised
     514an interface used to expose a specialised
    506515`allocator<T>` to the non-specific `abstract_base`. This process is easy to understand with some examples:
    507516
     
    527536{
    528537    // over-ride the make_copy method, providing our own means to make a clone
    529     Foo *make_copy(cloneable::abstract_allocator &amp;alloc) const
     538    Foo *make_copy(cloneable::abstract_allocator &alloc) const
    530539    {
    531540        Foo *copy = cloneable::create<Foo>(alloc);
     
    541550provide a custom clone override at all. If your class only members that have value
    542551semantics and can in turn be copy-constructed (including `std::containers`, and heterogenous::containers),
    543 then you do not need to provide any customisation.
    544 
    545 However, if your class contains pointers of any description, or references,
    546 then you will in general have to provide a sensible copy-constructor, or provide a custom clone override.
     552then you do not need to provide any customisation. So don't start by making a custom clone override method.
     553First, check your class to see if it is actually needed. Introducing a `make_copy()` method too early
     554or when not needed can create maintenance problems.
     555
     556__tip__ if your class contains pointers of any description, or references,
     557then you will in general have to at least provide a sensible copy-constructor, or provide a custom clone override.
    547558
    548559In summary, there are three stages of customisation:
     
    577588``
    578589
    579 More details are in the `clonable::traits<T>` structure.
     590More details are in the `clonable::traits<T>` structure. [@boost:/libs/cloneable/boost/cloneable/traits.hpp traits.hpp]
    580591
    581592[endsect]
     
    813824``
    814825
    815 ['Again, the names here have undergone a number of changes and remain in flux. Suggestions welcome!]
     826['__alert__ the names here have undergone a number of changes and remain in flux. Suggestions welcome!]
    816827
    817828`push_back` works just like with `list` and is not surprising. But the `as` and `cast` methods are new.
  • sandbox/cloneable/libs/cloneable/doc/html/cloneable/change_log.html

    r54657 r54658  
    2828</h2></div></div></div>
    2929<a name="cloneable.change_log.version_0_1"></a><h4>
    30 <a name="id657967"></a>
     30<a name="id687458"></a>
    3131      <a class="link" href="change_log.html#cloneable.change_log.version_0_1">Version 0.1</a>
    3232    </h4>
  • sandbox/cloneable/libs/cloneable/doc/html/cloneable/heterogenous_containers/vector.html

    r54634 r54658  
    5252      </p>
    5353<p>
    54         <span class="emphasis"><em>Again, the names here have undergone a number of changes and remain
    55         in flux. Suggestions welcome!</em></span>
     54        <span class="emphasis"><em><span class="inlinemediaobject"><img src="../../images/alert.png" alt="alert"></span> the names here have undergone a number of changes and
     55        remain in flux. Suggestions welcome!</em></span>
    5656      </p>
    5757<p>
  • sandbox/cloneable/libs/cloneable/doc/html/cloneable/tutorial.html

    r54657 r54658  
    128128    </p>
    129129<p>
    130       Note that we pass references to these functions rather than pointers, and these
    131       functions work for <span class="emphasis"><em>Cloneable</em></span> types and generally. We can
    132       also pass an allocator to these functions, but more on custom allocation later.
     130      <span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> we pass references to these functions rather than pointers,
     131      and these functions work for <span class="emphasis"><em>Cloneable</em></span> types and generally.
     132      We can also pass an allocator to these functions, but more on custom allocation
     133      later.
    133134    </p>
    134135<p>
  • sandbox/cloneable/libs/cloneable/doc/html/cloneable/tutorial/cloneable_traits.html

    r54638 r54658  
    5555<p>
    5656        More details are in the <code class="computeroutput"><span class="identifier">clonable</span><span class="special">::</span><span class="identifier">traits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
    57         structure.
     57        structure. <a href="../../../../../../libs/cloneable/boost/cloneable/traits.hpp" target="_top">traits.hpp</a>
    5858      </p>
    5959</div>
  • sandbox/cloneable/libs/cloneable/doc/html/cloneable/tutorial/controlling_construction.html

    r54639 r54658  
    5151        it is not default-constructible by passing the <code class="computeroutput"><span class="identifier">no_default_construction_tag</span></code>
    5252        type as a parameter to <code class="computeroutput"><span class="identifier">cloneable</span><span class="special">::</span><span class="identifier">base</span><span class="special">&lt;&gt;</span></code>. The order that you give the base-type
    53         or tag-types to <code class="computeroutput"><span class="identifier">cloneable</span><span class="special">::</span><span class="identifier">base</span><span class="special">&lt;&gt;</span></code> is not important and is dealt with
    54         correctly by the library.
     53        or tag-types to <code class="computeroutput"><span class="identifier">cloneable</span><span class="special">::</span><span class="identifier">base</span><span class="special">&lt;&gt;</span></code> is not important.
    5554      </p>
    5655<p>
     
    6463    <span class="identifier">string</span> <span class="identifier">str</span> <span class="special">=</span> <span class="string">"foo"</span><span class="special">;</span>
    6564    <span class="identifier">T0</span> <span class="special">*</span><span class="identifier">p</span> <span class="special">=</span> <span class="keyword">new</span> <span class="identifier">T0</span><span class="special">(</span><span class="identifier">str</span><span class="special">);</span>
    66     <span class="identifier">T0</span> <span class="special">*</span><span class="identifier">q</span> <span class="special">=</span> <span class="identifier">p</span><span class="special">-&gt;</span><span class="identifier">clone_as</span><span class="special">&lt;</span><span class="identifier">T0</span><span class="special">&gt;();</span>
    67     <span class="identifier">assert</span><span class="special">(&amp;</span><span class="identifier">q</span><span class="special">-&gt;</span><span class="identifier">str</span> <span class="special">==</span> <span class="special">&amp;</span><span class="identifier">str</span><span class="special">);</span>
     65    <span class="identifier">T0</span> <span class="special">*</span><span class="identifier">q</span> <span class="special">=</span> <span class="identifier">clone</span><span class="special">(*</span><span class="identifier">p</span><span class="special">);</span> <span class="comment">// or, p-&gt;clone_as&lt;T0&gt;();
     66</span>    <span class="identifier">assert</span><span class="special">(&amp;</span><span class="identifier">q</span><span class="special">-&gt;</span><span class="identifier">str</span> <span class="special">==</span> <span class="special">&amp;</span><span class="identifier">str</span><span class="special">);</span>
    6867   
    6968    <span class="comment">// demonstrate that attempting to create
     
    8887        A <code class="computeroutput"><span class="identifier">no_default_construction</span></code>
    8988        exception is thrown if you attempt to default-construct a type that has no
    90         default constructor.
     89        default constructor. As you would expect, if a Cloneable Q type derives from
     90        a non-default-constructable type, then Q is also not default-constructable.
     91      </p>
     92<p>
     93        Next, we'll look at how to use existing types that we can't change.
    9194      </p>
    9295</div>
  • sandbox/cloneable/libs/cloneable/doc/html/cloneable/tutorial/customising_the_cloning_process.html

    r54634 r54658  
    5555      </p>
    5656<p>
    57         Please ensure that you override the <code class="computeroutput"><span class="identifier">make_copy</span><span class="special">()</span></code> method correctly. It must return a type
    58         that is co-variant with the base you used for the derived type, and must
    59         be <code class="computeroutput"><span class="keyword">const</span></code>. If you make a mistake
    60         on the return type, the compiler will complain. But if you forget to make
    61         the method const, it will not be invoked when needed and there will be no
    62         warning or error.
     57        Please ensure that you override the <code class="computeroutput"><span class="identifier">make_copy</span><span class="special">()</span> <span class="keyword">const</span></code> method
     58        correctly. It must return a type that is co-variant with the base you used
     59        for the derived type, and should be <code class="computeroutput"><span class="keyword">const</span></code>.
     60        If you make a mistake on the return type, the compiler will complain. There
     61        is a non-const <code class="computeroutput"><span class="identifier">make_copy</span><span class="special">()</span></code> method as well. This will be invoked on
     62        a non-const original, then the const <code class="computeroutput"><span class="identifier">make_copy</span><span class="special">()</span> <span class="keyword">const</span></code> will
     63        be attempted before finally using the <code class="computeroutput"><span class="identifier">copy_construct</span><span class="special">()</span> <span class="keyword">const</span></code> method.
     64        To summarise:
     65      </p>
     66<div class="itemizedlist"><ul class="itemizedlist" type="disc">
     67<li class="listitem">
     68          Attempting to make a copy of a non-const original will invoke <code class="computeroutput"><span class="identifier">make_copy</span><span class="special">()</span></code>
     69</li>
     70<li class="listitem">
     71          If this fails or is not over-ridden, then the <code class="computeroutput"><span class="identifier">make_copy</span><span class="special">()</span> <span class="keyword">const</span></code>
     72          method is invoked.
     73        </li>
     74<li class="listitem">
     75          If this fails is or not over-ridden, then <code class="computeroutput"><span class="identifier">copy_construct</span><span class="special">()</span> <span class="keyword">const</span></code>
     76          is invoked.
     77        </li>
     78</ul></div>
     79<p>
     80        This provides a means for clones to be made that alter the original, if you
     81        need to do that. For <code class="computeroutput"><span class="keyword">const</span></code> originals,
     82        the process starts from step 2. All of these methods are over-loaded with
     83        a similar method that takes an <code class="computeroutput"><span class="identifier">abstract_allocator</span></code>
     84        argument.
    6385      </p>
    6486<p>
    65         This example uses the heap to make clones; we will next see how to make clones
    66         using any standard-compliant allocator type.
     87        Which is a nice segue into the next section. This example used the heap to
     88        make clones; we will next see how to make clones using any standard-compliant
     89        allocator type.
    6790      </p>
    6891</div>
  • sandbox/cloneable/libs/cloneable/doc/html/cloneable/tutorial/dealing_with_muliple_sub_objects.html

    r54638 r54658  
    3232        use the <code class="computeroutput"><span class="identifier">clone_as</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> and
    3333        <code class="computeroutput"><span class="identifier">create_as</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> methods
    34         to disambiguate which sub-type to clone or create.
     34        or functions to disambiguate which sub-type to clone or create.
    3535      </p>
    3636<p>
     
    5050    <span class="identifier">T2</span> <span class="special">*</span><span class="identifier">t2</span> <span class="special">=</span> <span class="keyword">new</span> <span class="identifier">T2</span><span class="special">();</span>
    5151   
     52    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">can_clone_as</span><span class="special">&lt;</span><span class="identifier">W</span><span class="special">&gt;());</span>
     53    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">can_clone_as</span><span class="special">&lt;</span><span class="identifier">T0</span><span class="special">&gt;());</span>
     54    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">can_clone_as</span><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">&gt;());</span>
     55    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">can_clone_as</span><span class="special">&lt;</span><span class="identifier">T2</span><span class="special">&gt;());</span>
     56   
     57    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">can_create_as</span><span class="special">&lt;</span><span class="identifier">W</span><span class="special">&gt;());</span>
     58    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">can_create_as</span><span class="special">&lt;</span><span class="identifier">T0</span><span class="special">&gt;());</span>
     59    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">can_create_as</span><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">&gt;());</span>
     60    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">can_create_as</span><span class="special">&lt;</span><span class="identifier">T2</span><span class="special">&gt;());</span>
     61   
    5262    <span class="comment">// clone sub-objects
    5363</span>    <span class="identifier">W</span> <span class="special">*</span><span class="identifier">t2_w</span> <span class="special">=</span> <span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">clone_as</span><span class="special">&lt;</span><span class="identifier">W</span><span class="special">&gt;();</span>
     64    <span class="identifier">T0</span> <span class="special">*</span><span class="identifier">t2_t0</span> <span class="special">=</span> <span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">clone_as</span><span class="special">&lt;</span><span class="identifier">T0</span><span class="special">&gt;();</span>
    5465    <span class="identifier">T1</span> <span class="special">*</span><span class="identifier">t2_t1</span> <span class="special">=</span> <span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">clone_as</span><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">&gt;();</span>
    55     <span class="identifier">T0</span> <span class="special">*</span><span class="identifier">t2_t0</span> <span class="special">=</span> <span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">clone_as</span><span class="special">&lt;</span><span class="identifier">T0</span><span class="special">&gt;();</span>
     66    <span class="identifier">T1</span> <span class="special">*</span><span class="identifier">t2_t2</span> <span class="special">=</span> <span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">clone_as</span><span class="special">&lt;</span><span class="identifier">T2</span><span class="special">&gt;();</span>
    5667   
    5768    <span class="comment">// create sub-objects
    5869</span>    <span class="identifier">W</span> <span class="special">*</span><span class="identifier">t2_w_new</span> <span class="special">=</span> <span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">create_as</span><span class="special">&lt;</span><span class="identifier">W</span><span class="special">&gt;();</span>
     70    <span class="identifier">T0</span> <span class="special">*</span><span class="identifier">t2_t0_new</span> <span class="special">=</span> <span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">create_as</span><span class="special">&lt;</span><span class="identifier">T0</span><span class="special">&gt;();</span>
    5971    <span class="identifier">T1</span> <span class="special">*</span><span class="identifier">t2_t1_new</span> <span class="special">=</span> <span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">create_as</span><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">&gt;();</span>
    60     <span class="identifier">T0</span> <span class="special">*</span><span class="identifier">t2_t0_new</span> <span class="special">=</span> <span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">create_as</span><span class="special">&lt;</span><span class="identifier">T0</span><span class="special">&gt;();</span>
    61    
     72    <span class="identifier">T2</span> <span class="special">*</span><span class="identifier">t2_t2_new</span> <span class="special">=</span> <span class="identifier">t2</span><span class="special">-&gt;</span><span class="identifier">create_as</span><span class="special">&lt;</span><span class="identifier">T2</span><span class="special">&gt;();</span>
    6273   
    6374    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
     
    6778      </p>
    6879<p>
    69         Note that if a sub-type S in type T is not default-constructabe, an exception
    70         of type no_default_construction will be thrown if you attempt to default-create
    71         a new S instance from a T instance.
     80        <span class="inlinemediaobject"><img src="../../images/alert.png" alt="alert"></span> if a sub-type <code class="computeroutput"><span class="identifier">S</span></code>
     81        in type <code class="computeroutput"><span class="identifier">T</span></code> is not default-constructabe,
     82        an exception of type <code class="computeroutput"><span class="identifier">no_default_construction</span></code>
     83        will be thrown if you attempt to default-create a new <code class="computeroutput"><span class="identifier">S</span></code>
     84        instance from a <code class="computeroutput"><span class="identifier">T</span></code> instance.
    7285      </p>
    7386</div>
  • sandbox/cloneable/libs/cloneable/doc/html/cloneable/tutorial/simple_hierarchical_cloning.html

    r54657 r54658  
    5353      </p>
    5454<p>
    55         Note that <code class="computeroutput"><span class="identifier">Animal</span></code> doesn't
    56         have to derive from anything, or have any special members or methods. Now
    57         let's use our base class to create a simple type hierarchy:
     55        <span class="inlinemediaobject"><img src="../../images/note.png" alt="note"></span> <code class="computeroutput"><span class="identifier">Animal</span></code>
     56        doesn't have to derive from anything, or have any special members or methods.
     57        Now let's use our base class to create a simple type hierarchy:
    5858      </p>
    5959<p>
     
    8282        Other than that, <code class="computeroutput"><span class="identifier">Cat</span></code> implements
    8383        the <code class="computeroutput"><span class="identifier">get_name</span></code> pure virtual
    84         method derived in the base class <code class="computeroutput"><span class="identifier">Animal</span></code>.
     84        method derived from the base class <code class="computeroutput"><span class="identifier">Animal</span></code>.
    8585      </p>
    8686<p>
     
    108108      </p>
    109109<p>
    110         Note that the <code class="computeroutput"><span class="identifier">clone</span><span class="special">()</span></code>
    111         method returns a pointer to the base class of the type hierarchy - in this
    112         case, <code class="computeroutput"><span class="identifier">Animal</span></code>. We had to use
    113         a dynamic cast to down-cast to our derived type.
     110        <span class="inlinemediaobject"><img src="../../images/note.png" alt="note"></span> the <code class="computeroutput"><span class="identifier">clone</span><span class="special">()</span></code> method returns a pointer to the base class
     111        of the type hierarchy - in this case, <code class="computeroutput"><span class="identifier">Animal</span></code>.
     112        We had to use a dynamic cast to down-cast to our derived type.
    114113      </p>
    115114<p>
     
    127126<p>
    128127        As we shall soon see, this is also handy when we have choices of which sub-object
    129         to clone.
     128        to clone. Of course, we could also use the free-function <code class="computeroutput"><span class="identifier">clone</span></code>:
     129      </p>
     130<p>
     131       
     132</p>
     133<pre class="programlisting"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">cloneable</span><span class="special">;</span>
     134
     135<span class="identifier">assert</span><span class="special">(</span><span class="identifier">can_clone_as</span><span class="special">&lt;</span><span class="identifier">Cat</span><span class="special">&gt;(*</span><span class="identifier">cat</span><span class="special">));</span>
     136<span class="identifier">Cat</span> <span class="special">*</span><span class="identifier">cloned</span> <span class="special">=</span> <span class="identifier">clone</span><span class="special">(*</span><span class="identifier">cat</span><span class="special">);</span>
     137</pre>
     138<p>
    130139      </p>
    131140<p>
     
    148157<p>
    149158        <code class="computeroutput"><span class="identifier">Dog</span></code> is just like a cat, but
    150         different. <code class="computeroutput"><span class="identifier">Labrador</span></code> is the
    151         first example we have seen that uses multiple inheritance. In this case,
    152         we are saying that a Labrador is-a Dog, and is Cloneable as either a Dog
    153         or a Labrador. Using these types:
     159        different <span class="inlinemediaobject"><img src="../../images/smiley.png" alt="smiley"></span>. <code class="computeroutput"><span class="identifier">Labrador</span></code>
     160        is the first example we have seen that uses multiple inheritance. In this
     161        case, we are saying that a Labrador is-a Dog, and is Cloneable as either
     162        a Dog or a Labrador. Using these types:
    154163      </p>
    155164<p>
     
    158167<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
    159168<span class="special">{</span>
    160     <span class="identifier">Labrador</span> <span class="special">*</span><span class="identifier">lab</span> <span class="special">=</span> <span class="keyword">new</span> <span class="identifier">Labrador</span><span class="special">();</span>
    161     <span class="identifier">Dog</span> <span class="special">*</span><span class="identifier">dog</span> <span class="special">=</span> <span class="identifier">lab</span><span class="special">-&gt;</span><span class="identifier">clone_as</span><span class="special">&lt;</span><span class="identifier">Dog</span><span class="special">&gt;();</span>
    162     <span class="identifier">Labrador</span> <span class="special">*</span><span class="identifier">cloned_lab</span> <span class="special">=</span> <span class="identifier">lab</span><span class="special">-&gt;</span><span class="identifier">clone_as</span><span class="special">&lt;</span><span class="identifier">Labrador</span><span class="special">&gt;();</span>
    163    
    164     <span class="identifier">assert</span><span class="special">(</span><span class="keyword">typeid</span><span class="special">(*</span><span class="identifier">dog</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">Dog</span><span class="special">));</span>
    165     <span class="identifier">assert</span><span class="special">(</span><span class="keyword">typeid</span><span class="special">(*</span><span class="identifier">cloned_lab</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">Labrador</span><span class="special">));</span>
     169    <span class="identifier">Animal</span> <span class="special">*</span><span class="identifier">lab</span> <span class="special">=</span> <span class="keyword">new</span> <span class="identifier">Labrador</span><span class="special">();</span>
     170    <span class="identifier">Animal</span> <span class="special">*</span><span class="identifier">lab_as_dog</span> <span class="special">=</span> <span class="identifier">lab</span><span class="special">-&gt;</span><span class="identifier">clone_as</span><span class="special">&lt;</span><span class="identifier">Dog</span><span class="special">&gt;();</span>
     171    <span class="identifier">Animal</span> <span class="special">*</span><span class="identifier">lab_clone</span> <span class="special">=</span> <span class="identifier">lab</span><span class="special">-&gt;</span><span class="identifier">clone_as</span><span class="special">&lt;</span><span class="identifier">Labrador</span><span class="special">&gt;();</span>
     172   
     173    <span class="identifier">assert</span><span class="special">(</span><span class="keyword">typeid</span><span class="special">(*</span><span class="identifier">lab_as_dog</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">Dog</span><span class="special">));</span>
     174    <span class="identifier">assert</span><span class="special">(</span><span class="keyword">typeid</span><span class="special">(*</span><span class="identifier">lab_clone</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">Labrador</span><span class="special">));</span>
     175   
     176    <span class="identifier">assert</span><span class="special">(!</span><span class="identifier">can_clone_as</span><span class="special">&lt;</span><span class="identifier">Labrador</span><span class="special">&gt;(</span><span class="identifier">lab_as_dog</span><span class="special">));</span>
    166177   
    167178    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
     
    176187      </p>
    177188<p>
    178         It should be noted that when using <code class="computeroutput"><span class="identifier">clone_as</span><span class="special">&lt;</span><span class="identifier">Ty</span><span class="special">&gt;</span></code>, we actually are making a type of <code class="computeroutput"><span class="identifier">Ty</span></code>, rather than making another type and
    179         casting up.
    180       </p>
    181 <p>
    182         We can also use the Cloneable library to make a new instance, with no duplication:
    183       </p>
    184 <p>
    185        
    186 </p>
    187 <pre class="programlisting"><span class="identifier">Animal</span> <span class="special">*</span><span class="identifier">MakeNew</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">cloneable</span><span class="special">::</span><span class="identifier">abstract_base</span><span class="special">&lt;</span><span class="identifier">Animal</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="identifier">animal</span><span class="special">)</span>
    188 <span class="special">{</span>
    189     <span class="keyword">return</span> <span class="identifier">animal</span><span class="special">.</span><span class="identifier">create_new</span><span class="special">();</span>
    190 <span class="special">}</span>
    191 
    192 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
    193 <span class="special">{</span>
    194     <span class="identifier">Cat</span> <span class="special">*</span><span class="identifier">cat</span> <span class="special">=</span> <span class="keyword">new</span> <span class="identifier">Cat</span><span class="special">();</span>
    195     <span class="identifier">Animal</span> <span class="special">*</span><span class="identifier">new_animal</span> <span class="special">=</span> <span class="identifier">MakeNew</span><span class="special">(*</span><span class="identifier">cat</span><span class="special">);</span>
     189        It should be noted that when using <code class="computeroutput"><span class="identifier">clone_as</span><span class="special">&lt;</span><span class="identifier">Ty</span><span class="special">&gt;</span></code>, we actually are making an instance of
     190        type <code class="computeroutput"><span class="identifier">Ty</span></code>, rather than making
     191        another type and casting up.
     192      </p>
     193<p>
     194        We can also use the Cloneable library to make a new derived instance from
     195        a base type:
     196      </p>
     197<p>
     198       
     199</p>
     200<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
     201<span class="special">{</span>
     202    <span class="identifier">Animal</span> <span class="special">*</span><span class="identifier">cat</span> <span class="special">=</span> <span class="keyword">new</span> <span class="identifier">Cat</span><span class="special">();</span>
     203    <span class="identifier">Animal</span> <span class="special">*</span><span class="identifier">new_animal</span> <span class="special">=</span> <span class="identifier">create_new</span><span class="special">(*</span><span class="identifier">cat</span><span class="special">);</span>
     204   
    196205    <span class="identifier">assert</span><span class="special">(</span><span class="keyword">typeid</span><span class="special">(*</span><span class="identifier">new_animal</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">Cat</span><span class="special">));</span>
     206   
    197207    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
    198208<span class="special">}</span>
     
    202212<p>
    203213        This will create a new derived animal type (not a new base), and return a
    204         pointer to the base. Here we used a free-function to make the new object,
    205         to show how to use the <code class="computeroutput"><span class="identifier">abstract_base</span></code>
    206         template structure. We used <code class="computeroutput"><span class="identifier">abstract_base</span><span class="special">&lt;</span><span class="identifier">Animal</span><span class="special">&gt;</span></code>, rather than just <code class="computeroutput"><span class="identifier">Animal</span></code>,
    207         as the base type argument for the <code class="computeroutput"><span class="identifier">MakeNew</span></code>
    208         function. This is because the base class we provided, <code class="computeroutput"><span class="identifier">Animal</span></code>,
    209         does not derive from anything and does not have any clone-related methods.
    210         These methods are added by the <code class="computeroutput"><span class="identifier">abstract_base</span><span class="special">&lt;&gt;</span></code> mix-in, which all derived <code class="computeroutput"><span class="identifier">Animal</span></code>s are implicitly convertible to.
     214        pointer to the base.
    211215      </p>
    212216<p>
    213217        This is the basics of the cloneability side of the library. But there are
    214218        a few more details and use-cases to cover before we get to the containers.
    215         The first of which is dealing with types that we can't change.
     219        The first of these details is dealing with types that are not default-constructable.
     220        This is a very useful part of the library, as it allows for containers with
     221        elements that are not default constructable and do not have assignment operations.
     222        We'll get to that in the containers tutorial, but for now let's quickly cover
     223        the basics in the next section.
    216224      </p>
    217225</div>
  • sandbox/cloneable/libs/cloneable/doc/html/cloneable/tutorial/using_custom_allocators.html

    r54634 r54658  
    3737        <code class="computeroutput"><span class="identifier">abstract_base</span></code> is given a
    3838        reference to an <code class="computeroutput"><span class="identifier">abstract_allocator</span></code>.
    39         This is an interface (containing only pure virtual methods) that is used
    40         to expose a specialised <code class="computeroutput"><span class="identifier">allocator</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
     39        This is an interface used to expose a specialised <code class="computeroutput"><span class="identifier">allocator</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
    4140        to the non-specific <code class="computeroutput"><span class="identifier">abstract_base</span></code>.
    4241        This process is easy to understand with some examples:
     
    7170<span class="special">{</span>
    7271    <span class="comment">// over-ride the make_copy method, providing our own means to make a clone
    73 </span>    <span class="identifier">Foo</span> <span class="special">*</span><span class="identifier">make_copy</span><span class="special">(</span><span class="identifier">cloneable</span><span class="special">::</span><span class="identifier">abstract_allocator</span> <span class="special">&amp;</span><span class="identifier">amp</span><span class="special">;</span><span class="identifier">alloc</span><span class="special">)</span> <span class="keyword">const</span>
     72</span>    <span class="identifier">Foo</span> <span class="special">*</span><span class="identifier">make_copy</span><span class="special">(</span><span class="identifier">cloneable</span><span class="special">::</span><span class="identifier">abstract_allocator</span> <span class="special">&amp;</span><span class="identifier">alloc</span><span class="special">)</span> <span class="keyword">const</span>
    7473    <span class="special">{</span>
    7574        <span class="identifier">Foo</span> <span class="special">*</span><span class="identifier">copy</span> <span class="special">=</span> <span class="identifier">cloneable</span><span class="special">::</span><span class="identifier">create</span><span class="special">&lt;</span><span class="identifier">Foo</span><span class="special">&gt;(</span><span class="identifier">alloc</span><span class="special">);</span>
     
    8887        have value semantics and can in turn be copy-constructed (including <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">containers</span></code>,
    8988        and heterogenous::containers), then you do not need to provide any customisation.
     89        So don't start by making a custom clone override method. First, check your
     90        class to see if it is actually needed. Introducing a <code class="computeroutput"><span class="identifier">make_copy</span><span class="special">()</span></code> method too early or when not needed can
     91        create maintenance problems.
    9092      </p>
    9193<p>
    92         However, if your class contains pointers of any description, or references,
    93         then you will in general have to provide a sensible copy-constructor, or
    94         provide a custom clone override.
     94        <span class="inlinemediaobject"><img src="../../images/tip.png" alt="tip"></span> if your class contains pointers of any description,
     95        or references, then you will in general have to at least provide a sensible
     96        copy-constructor, or provide a custom clone override.
    9597      </p>
    9698<p>
  • sandbox/cloneable/libs/cloneable/doc/html/index.html

    r54657 r54658  
    2929<div><p class="copyright">Copyright © 2009 Christian Schladetsch</p></div>
    3030<div><div class="legalnotice" title="Legal Notice">
    31 <a name="id657828"></a><p>
     31<a name="id687319"></a><p>
    3232        Distributed under the Boost Software License, Version 1.0. (See accompanying
    3333        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
     
    7575</div>
    7676<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
    77 <td align="left"><p><small>Last revised: July 04, 2009 at 21:44:10 GMT</small></p></td>
     77<td align="left"><p><small>Last revised: July 04, 2009 at 23:19:19 GMT</small></p></td>
    7878<td align="right"><div class="copyright-footer"></div></td>
    7979</tr></table>
  • sandbox/cloneable/libs/cloneable/test/tests.cpp

    r54656 r54658  
    198198        assert(t2->can_create_as<T2>());
    199199        assert(t2->can_create_as<W>());
     200
     201        // these free-functions currently do not work...
    200202   /* assert(can_clone_as<W>(*t2));
    201203    assert(can_clone_as<T0>(*t2));
Note: See TracChangeset for help on using the changeset viewer.