forked from peter-can-write/cpp-notes
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathallocators.html
More file actions
39 lines (39 loc) · 13 KB
/
allocators.html
File metadata and controls
39 lines (39 loc) · 13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/><meta name="exporter-version" content="Evernote Mac 6.3 (452849)"/><meta name="altitude" content="519.2467041015625"/><meta name="author" content="petergoldsborough@hotmail.com"/><meta name="created" content="2015-08-02 19:10:41 +0000"/><meta name="latitude" content="46.62887885049156"/><meta name="longitude" content="13.82460902803554"/><meta name="source" content="desktop.mac"/><meta name="updated" content="2015-08-02 19:30:54 +0000"/><title>Allocators</title></head><body>
<div>Allocators are special template classes used by the standard containers to allocate and deallocate memory. If you want to define your own, follow this advice:</div>
<div><br/></div>
<ul>
<li>Make your allocator a template, with the template parameter T representing the type of objects for which you are allocating memory.</li>
<li>Provide the internal typedefs ‘pointer' and ‘reference’, but always have ‘pointer’ be T* and ‘reference’ be T&.</li>
<li>Never give your allocators 'per-object state’, i.e. do not let them have non-static data (all allocators of one type should be the same).</li>
<li>Provide a nested re-bind template struct to make it possible to use the same allocator but for a different type.</li>
</ul>
<div><br/></div>
<div>The last point refers to the fact that all node-based (associative) containers in the standard do not use the allocator you pass to it (e.g. Allocator<int> for list<int>) but actually need to use the same allocator type, but for its private ‘node’ types (that hold the ’next’ and ‘previous’ pointers for a linked list). I.e.:</div>
<div><br/></div>
<div><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">template</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">typename</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">T><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">struct</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">Custom_Allocator<br/>
{<br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">typedef</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">T value_type;<br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">typedef</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">T* pointer;<br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">typedef</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">T& reference;<br/>
<br/>
T* allocate(</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #02a1f3">std</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">::</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #02a1f3">size_t</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">numberOfObjects);<br/>
<br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">void</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">deallocate(T* ptr,</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #02a1f3">std</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">::</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #02a1f3">size_t</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">numberOfObjects);<br/>
<br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// There is no such thing as a templated</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// typedef or using declaration, so you</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// provide this nested struct that is</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// itself templated and that just provides</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// the typedef to have access to the allocator</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// class but for a different type. If there</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// were no rebind struct there would be no way</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// to access the un-templated type of an allocator</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// passed to a container or so, since an instance</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// of a template class for a certain type is entirely</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// unaware that it is an instance of a template class</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// (since it is simply an instance of the statically,</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// compiler-generated version of the class for type T)</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">template</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">typename</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">U><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">struct</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">rebind<br/>
{<br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">typedef</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #4f8187">Custom_Allocator</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><U> other;<br/>
};<br/>
};<br/>
<br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">template</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">typename</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">Alloc><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">void</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">foo(</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">const</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">Alloc& allocator)<br/>
{<br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// Alloc has no idea that it is actually of</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// type Custom_Allocator<T></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">typename</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">Alloc::</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">template</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">rebind<</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #02a1f3">std</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">::</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #02a1f3">string</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">>::other allocator_for_string;<br/>
<br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #848784">// bla</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><br/>
}<br/>
<br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">int</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">main(</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">int</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">argc,</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">char</span> <span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">* argv[])<br/>
{<br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #4f8187">Custom_Allocator</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures"><</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #e448ab">int</span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures">> allocator_for_int;<br/>
<br/></span><span style="font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #31595d">foo</span><span style="font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;"><span style="font-size: 11px;"><span style="font-family: Menlo;">(allocator_for_int);</span></span></span></div>
<div><span style="font-size: 11px;"><span style="font-family: Menlo;">}</span></span></div>
<div><span style="font-size: 11px;"><span style="font-family: Menlo;"><br/></span></span></div>
<div><font face="Menlo"><span style="font-size: 11px;">Note also the differences in signature between </span><span style="font-size: 11px; line-height: 15px;">‘</span><span style="font-size: 11px;">operator new</span><span style="font-size: 11px; line-height: 15px;">’</span><span style="font-size: 11px;"> and the </span><span style="font-size: 11px; line-height: 15px;">‘</span><span style="font-size: 11px;">allocate</span><span style="font-size: 11px; line-height: 15px;">’</span><span style="font-size: 11px;"> method of the Allocator:</span></font></div>
<div><span style="font-size: 11px;"><span style="font-family: Menlo;"><br/></span></span></div>
<div><span style="font-size: 11px;"><span style="font-family: Menlo;">void* operator new(std::size_t numberOfBytes);</span></span></div>
<div><span style="font-size: 11px;"><span style="font-family: Menlo;"><br/></span></span></div>
<div><span style="font-size: 11px;"><span style="font-family: Menlo;">T* Allocator<T>::allocate(std::size_t numberOfObjects);</span></span></div>
<div><span style="font-size: 11px;"><span style="font-family: Menlo;"><br/></span></span></div>
</body></html>