⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 defines.htm

📁 这是关于VC++中的STL容器的资料,包括了STL容器各个类之间关系以及类的说明
💻 HTM
字号:

<html>
<head>
<title>definitions</title>
<head>

<body bgcolor="#FFFFFF">

<a name="dynamic-cast"></a>

<h2>Dynamic Casting and bad_cast class</h2>
<p>

Sometimes casting an object may be necessary. There are four type cast operators:
</p>
<pre>

     const_cast

     reinterpret_cast

     static_cast

     dynamic_cast

</pre>
<p>

The purpose of a dynamic_cast is to upcast an object within a class hierarchy. The object to be 
upcast has to be a direct or indirect descendant of the type that is casting. For example:
</p>
<pre>

     expression_component* Expression;
     operator_type* Operator;
     ...

     Expression = dynamic_cast<expression_component *> Operator;

</pre>
<p>
This statement assigns Expression a pointer to expression_component object. The Operator 
object of type operator_ type has been cast to expression_component. The expression_component 
is base class for operator_type. If operator_type had not been derived from 
expression_component then the operation would have returned a null pointer. It is called an 
upcast because the hierarchy has the base classes closer to the root of the hierarchy therefore 
casting to base classes moves upward in the structure. <br>
<br>
If the dynamic_cast uses a reference instead of a pointer:
</p>
<pre>

      dynamic_cast<R& > (p);

</pre>
<p>
and the reference is not to a direct or indirect base class of type p then a bad_cast exception is 
thrown by dynamic_cast. 
</p>

<hr>
<a name="typeid"></a>
<h2>The typeid Operator</h2>
<p>
The typeid operator will accept a pointer when dereferenced evaluates to a type:<br>
</p>
<pre>

     typeid(*P);

</pre>
<p>
If the pointer points to a null value then the typeid operator will throw a bad_typeid exception.
</p>
<hr>

<a name="bidirectional"><h2>Bidirectional Iterator</h2></a>
<p>
Bidirectional iterators can perform all of the operations of the forward iterators with the 
additional ability to move in either direction sequentially. The term bidirectional  means both 
directions. This means that the bidirectional iterator must perform postfix and prefix 
decrementation. These iterators can make multiple passes in either direction. These are the 
requirements for the bidirectional iterators:
</p>
<pre>

     read, dereference and assign (on right side of assignment)

     write, dereference and assign (on left side of assignment) increment and decrement

     test for equality or inequality

</pre>
<p>
The bidirectional iterator can move in a forward or backward direction as well as read and write 
elements to a container.
</p>
<hr>

<a name="random"><h2>Random Access Iterators</h2></a>
<p>
The most powerful iterator and the iterator that completely models a pointer are the random 
access iterators. Random access operators define postfix and prefix increments and decrements. 
They are sequential iterators and also direct access iterators. They can read objects from an input 
source and write objects to an output source.  Random access iterators can perform all of the 
operations of the bidirectional iterators with the additional ability to jump directly to any element 
in the container. In order for the random access iterator to jump to and access any element in the 
container, the subscript operator must be defined. The iterator must also have the ability to do 
relative addressing by using pointer arithmetic. Operators such as '+', '-', '+=', and '-=' must all be 
defined for this category of iterator. They must also define relational operations for ordering the 
elements. The '&gt;', '&lt;', '&gt;=', and '&lt;=' operators are defined. <br>
<br>
These are the requirements for random access iterators:
</p>
<pre>

     read, dereference and assign (on right side of assignment)

     write, dereference and assign (on left side of assignment)

     increment and decrement

     test for equality or inequality

     subscript operation

     relative addressing with pointer arithmetic (+, - , +=, -= operators)

     relational operations for ordering elements (&gt;, &lt;, &gt;=, &lt;=)

</pre>

		
<a name="io"><h2>Input and Output Iterators</h2></a>
<p>
The least powerful of the iterators are input and output iterators. They are the least powerful 
because they only perform the basic iterator operations and the output iterator does not have 
equality and inequality operations defined. The input iterator reads objects from an input source 
and stores the object. Examples of input sources are containers or istreams. The dereferencing of 
an input iterator must allow the object to be read and assigned. The input iterator does not have to 
allow the object to be altered necessarily. Dereferencing appears on the right side of the 
assignment operation not on the left side:<br>
<br>
</p>
</pre

     ... = *p;  // reading a value

     *p = ...;  // writing a value

</pre>
<p>
Input iterators are  sequential iterators. If an input iterator points to the first object in the input 
source, the iterator can be incremented until it points to the past-the-end value. Therefore, all of 
the objects from the input source must be accessible by means of the post and prefix 
incrementation. The prefix operation returns a reference to itself.  The postfix operation returns a 
copy of itself before incrementation. Algorithms using input iterators should not attempt to 
traverse through an input source, copy the value of the iterator and then use it to traverse through 
an input source a second time. Input iterators should only be used for a single pass through the 
input source.<br>
<br>
Input iterator must also define equality and inequality operations. If two iterators are equal, it 
does not guarantee that subsequent iterators are also equal. In other words:<br>
<br>
<pre>

     if a == b,does not mean ++a == ++b 

</pre>
<p>
But if the iterators are equal it does imply that the objects the iterators are pointing to are equal. 
In other words:<br>
<br>
<pre>

     if a == b,does mean *a == *b

</pre>
<p>
For this iterator or any other iterator that defines an equality, there must be a difference_type that 
holds the distance between two elements.<br>
<br>
These are the requirements of the input iterators:<br>
</p>
<pre>

     read, dereference and assign (on right sides of assignment)

     increment

     test for equality or inequality

</pre>
<p>
Output iterators write objects. Objects can be written to a container or ostream. The 
dereferencing of an output iterator must allow objects to be altered and written but does not 
guarantee that objects can be read. In this case, dereferencing appears on the left side of an 
assignment operation. Assignment occurs only once. Post and prefix incrementation must be 
allowed. They are also sequential iterators. Like input iterators, output iterators should be used 
for a single pass. These are the requirements of the output iterators:<br>
<br>
</p>
<pre>

     write, dereference and assign (on left sides of assignment)

     increment

</pre>
<p>

Consider this:
</p>
<pre>

     void new_content(InputIterator first, InputIterator last, 
                        OutputIterator out)
     {
          while (first != last){
                  *out++ = *first++;
          }
     }

</pre>
<p>
first and last are both input iterators. Objects pointed to by first are sequentially assigned to the 
output iterator out. The out iterator can be another container or associated with a file or standard 
output. If out is associated with  standard output then this function will produce the same results 
as the original function content.
</p>

<a name="insert"><h2>Insert Iterators</h2></a>
<p>
Insertion iterators are adaptions of the output iterators that supply the write functionality. When 
insert iterators are used, the values are inserted into a location in the container and do not 
overwrite an already existing value. The insert adaptor puts the container into insert mode rather 
than overwrite mode. The front _insert_iterator  insert objects at the beginning of a container and 
the back_insert_iterator insert objects at the back or end of a container. The insert_iterator insert 
objects at the location right before where the iterator is pointing. The front_insert_iterator, 
back_insert_iterator and insert_iterator all require a reference to the container the objects are to 
be inserted. The insert_iterator also requires an iterator that points to a location in the container. 
The inserters use the container's  methods to do the insertion. The front_insert_iterator uses a 
container's push_front() method. The push_front() method  The back_insert_iterator uses a 
container's push_back() method. The insert_iterator uses a container's insert() method. Any 
container that supplies the appropriate method can be used by these inserters.They inherit the 
base class iterator and contain a reference to the container.
</p>

<a name="reverse"><h2>Reverse Iterators</h2></a>
<p>
Reverse iterators are adaptations of bidirectional and random access iterators. Reverse 
iterators transforms the bidirectional and random access iterators to do a traversal in the reverse 
direction. They move through the container in the opposite direction. The interface is the same as 
the interface for the bidirectional or random access iterator except the container traversal is done 
in reverse. There are two types or reverse iterators:
</p>
<pre>

     reverse_iterator

     const_reverse_iterator

</pre>
<p>
The reverse_iterator is mutable and const_reverse_iterator is constant. The reverse iterators are 
already apart of every container.  For example to use the reverse iterator for a list, an object P 
could be declared of type:
</p>
<pre>

     list&lt;double&gt;::reverse_iterator P;

</pre>
<p>
P can be initialized with an iterator that points to the end of the container MyList:
</p>
<pre>

     list&lt;double&gt; MyList;
     P = MyList.rbegin();

</pre>
<p>
Any traversing through the list, e.g., P++, would actually be moving in the reverse direction. The 
methods,  rbegin() and rend() can return both constant and mutable reverse iterator types. The 
rbegin() method points to the same element as the end() method. The rend() method points to the 
same element as the begin() method. Since the end() method actually points to the past-the-end 
value of the container, an adjustment is made when the reverse iterator returned by rbegin() is 
dereferenced. The dereference operator will actually return current - 1 to compensate. Therefore, 
if the iterator is dereferenced it will not attempt to dereference the iterator pointing to the past-
the-end location of the container. It will return the element right before that location. <br>
<br>
Whether the reverse iterator is random access or bidirectional will depend on which type of 
iterator the container supports. If the container supports bidirectional iterators then the reverse 
iterator will be an adaptation of the bidirectional iterator. If the container supports random access 
iterators then the reverse iterator will be an adaptation of the random access iterator. The 
rbegin(), rend() will return either a reverse bidirectional or a reverse random access iterator. If 
the reverse iterator is a random access iterator then all of the iterator arithmetic and subscript 
operations can be done. <br>
<br>
Algorithms can use reverse iterators. The algorithms will function as they do with regular 
iterators except the algorithms will  work with the container in reverse. For example, a sort 
algorithm would sort the elements of the container in reverse order. The find algorithm would 
find the last occurrence of an element instead of the first occurrence.  With the reverse iterators, 
incrementation decrements the iterator and decrementation increments the iterator.
</p>

<a name="buffer"><h2>Stream and Stream Buffer Iterators</h2></a>
<p>
 The stream and stream buffer iterators make it possible for algorithms to work with the iostream. 
They are also the connection between the iostream classes and the standard containers. Stream 
and stream buffer iterators can be used to read data from a stream and write it to a container or 
read data from a container and write it to a stream. The standard has two stream iterators and two 
stream buffer iterators:<br>
<br>
</p>
<pre>

     ostream_iterator

     ostreambuf_iterator

     istream_iterator
 
     istreambuf_iterator 

</pre>
<p>
The ostream_iterator and ostreambuf_iterator work with the ostream family of classes. The 
istream_iterator and istreambuf_iterator work with the istream family. The ostream_iterator and 
ostreambuf_iterator are output iterator types. The istream_iterator and istreambuf_iterator are 
input iterator types. These iterators classes inherit the base class iterator. Any algorithm that 
accepts input iterators can be used with the istream family of classes and any algorithm that 
accepts output iterators can be used with the ostream family of classes. Stream iterators reads or 
writes successive elements of a type using the insertion and extraction operators, &lt;&lt; and &gt;&gt;.  
Stream buffers do insertion and extraction at a lower level, character by character. If user-defined 
types or special characters are used, these operators must be defined for them. 
</pre>


</body>

</html>


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -