📄 defines.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 '>', '<', '>=', and '<=' 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 (>, <, >=, <=)
</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<double>::reverse_iterator P;
</pre>
<p>
P can be initialized with an iterator that points to the end of the container MyList:
</p>
<pre>
list<double> 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, << and >>.
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 + -