C++ Primer, Fifth Edition
Exercises Section 14.5
Exercise 14.26: Define subscript operators for your StrVec, String,
StrBlob, and StrBlobPtr classes.
14.6. Increment and Decrement Operators
The increment (++) and decrement (--) operators are most often implemented for
iterator classes. These operators let the class move between the elements of a
sequence. There is no language requirement that these operators be members of the
class. However, because these operators change the state of the object on which they
operate, our preference is to make them members.
For the built-in types, there are both prefix and postfix versions of the increment
and decrement operators. Not surprisingly, we can define both the prefix and postfix
instances of these operators for our own classes as well. We’ll look at the prefix
versions first and then implement the postfix ones.
Best Practices
Classes that define increment or decrement operators should define both the
prefix and postfix versions. These operators usually should be defined as
members.
Defining Prefix Increment/Decrement Operators
To illustrate the increment and decrement operators, we’ll define these operators for
our StrBlobPtr class (§ 12.1.6, p. 474):
Click here to view code image
class StrBlobPtr {
public:
// increment and decrement
StrBlobPtr& operator++();       // prefix operators
StrBlobPtr& operator--();
// other members as before
};
Best Practices
To be consistent with the built-in operators, the prefix operators should
www.it-ebooks.info
Pdf to powerpoint - C# Create PDF from PowerPoint Library to convert pptx, ppt to PDF in C#.net, ASP.NET MVC, WinForms, WPF
Online C# Tutorial for Creating PDF from Microsoft PowerPoint Presentation
export pdf into powerpoint; how to convert pdf to ppt for
Pdf to powerpoint - VB.NET Create PDF from PowerPoint Library to convert pptx, ppt to PDF in vb.net, ASP.NET MVC, WinForms, WPF
VB.NET Tutorial for Export PDF file from Microsoft Office PowerPoint
image from pdf to powerpoint; convert pdf to powerpoint online for
C++ Primer, Fifth Edition
return a reference to the incremented or decremented object.
The increment and decrement operators work similarly to each other—they call
check to verify that the StrBlobPtr is still valid. If so, check also verifies that its
given index is valid. If check doesn’t throw an exception, these operators return a
reference to this object.
In the case of increment, we pass the current value of curr to check. So long as
that value is less than the size of the underlying vector, check will return. If curr
is already at the end of the vector, check will throw:
Click here to view code image
// prefix: return a reference to the incremented/decremented object
StrBlobPtr& StrBlobPtr::operator++()
{
// if curr already points past the end of the container, can't increment it
check(curr, "increment past end of StrBlobPtr");
++curr;       // advance the current state
return *this;
}
StrBlobPtr& StrBlobPtr::operator--()
{
// if curr is zero, decrementing it will yield an invalid subscript
--curr;       // move the current state back one element
check(-1, "decrement past begin of StrBlobPtr");
return *this;
}
The decrement operator decrements curr before calling check. That way, if curr
(which is an unsigned number) is already zero, the value that we pass to check will
be a large positive value representing an invalid subscript (§ 2.1.2, p. 36).
Differentiating Prefix and Postfix Operators
There is one problem with defining both the prefix and postfix operators: Normal
overloading cannot distinguish between these operators. The prefix and postfix
versions use the same symbol, meaning that the overloaded versions of these
operators have the same name. They also have the same number and type of
operands.
To solve this problem, the postfix versions take an extra (unused) parameter of type
int. When we use a postfix operator, the compiler supplies 0 as the argument for
this parameter. Although the postfix function can use this extra parameter, it usually
should not. That parameter is not needed for the work normally performed by a
postfix operator. Its sole purpose is to distinguish a postfix function from the prefix
version.
www.it-ebooks.info
Online Convert PowerPoint to PDF file. Best free online export
Online Powerpoint to PDF Converter. Download Free Trial. Then just wait until the conversion from Powerpoint to PDF is complete and download the file.
pdf to ppt converter online; convert pdf file into ppt
RasterEdge XDoc.PowerPoint for .NET - SDK for PowerPoint Document
Able to view and edit PowerPoint rapidly. Convert. Convert PowerPoint to PDF. Convert PowerPoint to HTML5. Convert PowerPoint to Tiff. Convert PowerPoint to Jpeg
pdf to powerpoint converter; pdf conversion to powerpoint
C++ Primer, Fifth Edition
We can now add the postfix operators to StrBlobPtr:
Click here to view code image
class StrBlobPtr {
public:
// increment and decrement
StrBlobPtr operator++(int);    // postfix operators
StrBlobPtr operator--(int);
// other members as before
};
Best Practices
To be consistent with the built-in operators, the postfix operators should
return the old (unincremented or undecremented) value. That value is
returned as a value, not a reference.
The postfix versions have to remember the current state of the object before
incrementing the object:
Click here to view code image
// postfix: increment/decrement the object but return the unchanged value
StrBlobPtr StrBlobPtr::operator++(int)
{
// no check needed here; the call to prefix increment will do the check
StrBlobPtr ret = *this;   // save the current value
++*this;     // advance one element; prefix ++ checks the increment
return ret;  // return the saved state
}
StrBlobPtr StrBlobPtr::operator--(int)
{
// no check needed here; the call to prefix decrement will do the check
StrBlobPtr ret = *this;  // save the current value
--*this;     // move backward one element; prefix -- checks the
decrement
return ret;  // return the saved state
}
Each of our operators calls its own prefix version to do the actual work. For example,
the postfix increment operator executes
++*this
This expression calls the prefix increment operator. That operator checks that the
increment is safe and either throws an exception or increments curr. Assuming
www.it-ebooks.info
C# WinForms Viewer: Load, View, Convert, Annotate and Edit
C#: Create PDF from PowerPoint; C#: Create PDF from Tiff; C#: Convert PDF to Word; C#: Convert PDF to Tiff; Convert Microsoft Office PowerPoint to PDF (.pdf).
how to add pdf to powerpoint slide; convert pdf to ppt
How to C#: Overview of Using XDoc.PowerPoint
How to C#: Overview of Using XDoc.PowerPoint. Overview for How to Use XDoc.PowerPoint in C# .NET Programming Project. PowerPoint Conversion.
convert pdf into ppt online; converting pdf to powerpoint
C++ Primer, Fifth Edition
check doesn’t throw an exception, the postfix functions return the stored copy in
ret. Thus, after the return, the object itself has been advanced, but the value
returned reflects the original, unincremented value.
Note
The int parameter is not used, so we do not give it a name.
Calling the Postfix Operators Explicitly
As we saw on page 553, we can explicitly call an overloaded operator as an alternative
to using it as an operator in an expression. If we want to call the postfix version using
a function call, then we must pass a value for the integer argument:
Click here to view code image
StrBlobPtr p(a1); // p points to the vector inside a1
p.operator++(0);  // call postfix operator++
p.operator++();   // call prefix  operator++
The value passed usually is ignored but is necessary in order to tell the compiler to
use the postfix version.
Exercises Section 14.6
Exercise 14.27: Add increment and decrement operators to your
StrBlobPtr class.
Exercise 14.28: Define addition and subtraction for StrBlobPtr so that
these operators implement pointer arithmetic (§ 3.5.3, p. 119).
Exercise 14.29: We did not define a const version of the increment and
decrement operators. Why not?
14.7. Member Access Operators
The dereference (*) and arrow (->) operators are often used in classes that
represent iterators and in smart pointer classes (§ 12.1, p. 450). We can logically add
these operators to our StrBlobPtr class as well:
Click here to view code image
class StrBlobPtr {
public:
www.it-ebooks.info
C# HTML5 Viewer: Load, View, Convert, Annotate and Edit PowerPoint
Such as load and view PowerPoint without Microsoft Office software installed, convert PowerPoint to PDF file, Tiff image and HTML file, as well as add
change pdf to powerpoint on; online pdf converter to powerpoint
C# powerpoint - Convert PowerPoint to PDF in C#.NET
C# PowerPoint - Convert PowerPoint to PDF in C#.NET. Online C# Tutorial for Converting PowerPoint to PDF (.pdf) Document. PowerPoint to PDF Conversion Overview.
pdf picture to powerpoint; pdf page to powerpoint
C++ Primer, Fifth Edition
std::string& operator*() const
{ auto p = check(curr, "dereference past end");
return (*p)[curr];  // (*p) is the vector to which this object points
}
std::string* operator->() const
{ // delegate the real work to the dereference operator
return & this->operator*();
}
// other members as before
};
The dereference operator checks that curr is still in range and, if so, returns a
reference to the element denoted by curr. The arrow operator avoids doing any
work of its own by calling the dereference operator and returning the address of the
element returned by that operator.
Note
Operator arrow must be a member. The dereference operator is not required
to be a member but usually should be a member as well.
It is worth noting that we’ve defined these operators as const members. Unlike the
increment and decrment operators, fetching an element doesn’t change the state of a
StrBlobPtr. Also note that these operators return a reference or pointer to
nonconst string. They do so because we know that a StrBlobPtr can only be
bound to a nonconst StrBlob (§ 12.1.6, p. 474).
We can use these operators the same way that we’ve used the corresponding
operations on pointers or vector iterators:
Click here to view code image
StrBlob a1 = {"hi", "bye", "now"};
StrBlobPtr p(a1);            // p points to the vector inside a1
*p = "okay";                 // assigns to the first element in a1
cout << p->size() << endl;   // prints 4, the size of the first element in
a1
cout << (*p).size() << endl; // equivalent to p->size()
Constraints on the Return from Operator Arrow
As with most of the other operators (although it would be a bad idea to do so), we
can define operator* to do whatever processing we like. That is, we can define
operator* to return a fixed value, say, 42, or print the contents of the object to
which it is applied, or whatever. The same is not true for overloaded arrow. The arrow
operator never loses its fundamental meaning of member access. When we overload
www.it-ebooks.info
VB.NET PowerPoint: Read, Edit and Process PPTX File
How to convert PowerPoint to PDF, render PowerPoint to SVG, transform PowerPoint to TIFF and convert PowerPoint to raster images with featured rendering
drag and drop pdf into powerpoint; convert pdf back to powerpoint
C# PDF Convert: How to Convert MS PPT to Adobe PDF Document
C#: Create PDF from PowerPoint; C#: Create PDF from Tiff; C#: Convert PDF to Word; C#: Convert PDF to Tiff; C# Tutorial: How to Convert PowerPoint to PDF.
convert pdf to editable powerpoint online; add pdf to powerpoint slide
C++ Primer, Fifth Edition
arrow, we change the object from which arrow fetches the specified member. We
cannot change the fact that arrow fetches a member.
When we write point->mem, point must be a pointer to a class object or it must
be an object of a class with an overloaded operator->. Depending on the type of
point, writing point->mem is equivalent to
Click here to view code image
(*point).mem;          // point is a built-in pointer type
point.operator()->mem; // point is an object of class type
Otherwise the code is in error. That is, point->mem executes as follows:
1. If point is a pointer, then the built-in arrow operator is applied, which means
this expression is a synonym for (*point).mem. The pointer is dereferenced
and the indicated member is fetched from the resulting object. If the type
pointed to by point does not have a member named mem, then the code is in
error.
2. If point is an object of a class that defines operator->, then the result of
point.operator->() is used to fetch mem. If that result is a pointer, then
step 1 is executed on that pointer. If the result is an object that itself has an
overloaded operator->(), then this step is repeated on that object. This
process continues until either a pointer to an object with the indicated member
is returned or some other value is returned, in which case the code is in error.
Note
The overloaded arrow operator 
must
return either a pointer to a class type or
an object of a class type that defines its own operator arrow.
Exercises Section 14.7
Exercise 14.30: Add dereference and arrow operators to your StrBlobPtr
class and to the ConstStrBlobPtr class that you defined in exercise 12.22
from § 12.1.6 (p. 476). Note that the operators in constStrBlobPtr must
return const references because the data member in constStrBlobPtr
points to a const vector.
Exercise 14.31: Our StrBlobPtr class does not define the copy
constructor, assignment operator, or a destructor. Why is that okay?
Exercise 14.32: Define a class that holds a pointer to a StrBlobPtr.
Define the overloaded arrow operator for that class.
www.it-ebooks.info
C++ Primer, Fifth Edition
14.8. Function-Call Operator
Classes that overload the call operator allow objects of its type to be used as if they
were a function. Because such classes can also store state, they can be more flexible
than ordinary functions.
As a simple example, the following struct, named absInt, has a call operator
that returns the absolute value of its argument:
Click here to view code image
struct absInt {
int operator()(int val) const {
return val < 0 ? -val : val;
}
};
This class defines a single operation: the function-call operator. That operator takes
an argument of type int and returns the argument’s absolute value.
We use the call operator by applying an argument list to an absInt object in a way
that looks like a function call:
Click here to view code image
int i = -42;
absInt absObj;      // object that has a function-call operator
int ui = absObj(i); // passes i to absObj.operator()
Even though absObj is an object, not a function, we can “call” this object. Calling an
object runs its overloaded call operator. In this case, that operator takes an int value
and returns its absolute value.
Note
The function-call operator must be a member function. A class may define
multiple versions of the call operator, each of which must differ as to the
number or types of their parameters.
Objects of classes that define the call operator are referred to as function objects.
Such objects “act like functions” because we can call them.
Function-Object Classes with State
Like any other class, a function-object class can have additional members aside from
www.it-ebooks.info
C++ Primer, Fifth Edition
operator(). Function-object classes often contain data members that are used to
customize the operations in the call operator.
As an example, we’ll define a class that prints a string argument. By default, our
class will write to cout and will print a space following each string. We’ll also let
users of our class provide a different stream on which to write and provide a different
separator. We can define this class as follows:
Click here to view code image
class PrintString {
public:
PrintString(ostream &o = cout, char c = ' '):
os(o), sep(c) { }
void operator()(const string &s) const { os << s << sep;
}
private:
ostream &os;   // stream on which to write
char sep;      // character to print after each output
};
Our class has a constructor that takes a reference to an output stream and a
character to use as the separator. It uses cout and a space as default arguments (§
6.5.1, p. 236) for these parameters. The body of the function-call operator uses these
members when it prints the given string.
When we define PrintString objects, we can use the defaults or supply our own
values for the separator or output stream:
Click here to view code image
PrintString printer;   // uses the defaults; prints to cout
printer(s);            // prints s followed by a space on cout
PrintString errors(cerr, '\n');
errors(s);             // prints s followed by a newline on cerr
Function objects are most often used as arguments to the generic algorithms. For
example, we can use the library for_each algorithm (§ 10.3.2, p. 391) and our
PrintString class to print the contents of a container:
Click here to view code image
for_each(vs.begin(), vs.end(), PrintString(cerr, '\n'));
The third argument to for_each is a temporary object of type PrintString that
we initialize from cerr and a newline character. The call to for_each will print each
element in vs to cerr followed by a newline.
Exercises Section 14.8
Exercise 14.33: How many operands may an overloaded function-call
operator take?
www.it-ebooks.info
C++ Primer, Fifth Edition
Exercise 14.34: Define a function-object class to perform an if-then-else
operation: The call operator for this class should take three parameters. It
should test its first parameter and if that test succeeds, it should return its
second parameter; otherwise, it should return its third parameter.
Exercise 14.35: Write a class like PrintString that reads a line of input
from an istream and returns a string representing what was read. If the
read fails, return the empty string.
Exercise 14.36: Use the class from the previous exercise to read the
standard input, storing each line as an element in a vector.
Exercise 14.37: Write a class that tests whether two values are equal. Use
that object and the library algorithms to write a program to replace all
instances of a given value in a sequence.
14.8.1. Lambdas Are Function Objects
In the previous section, we used a PrintString object as an argument in a call to
for_each. This usage is similar to the programs we wrote in § 10.3.2 (p. 388) that
used lambda expressions. When we write a lambda, the compiler translates that
expression into an unnamed object of an unnamed class (§ 10.3.3, p. 392). The
classes generated from a lambda contain an overloaded function-call operator. For
example, the lambda that we passed as the last argument to stable_sort:
Click here to view code image
// sort words by size, but maintain alphabetical order for words of the same size
stable_sort(words.begin(), words.end(),
[](const string &a, const string &b)
{ return a.size() < b.size();});
acts like an unnamed object of a class that would look something like
Click here to view code image
class ShorterString {
public:
bool operator()(const string &s1, const string &s2)
const
{ return s1.size() < s2.size(); }
};
The generated class has a single member, which is a function-call operator that takes
two strings and compares their lengths. The parameter list and function body are
the same as the lambda. As we saw in § 10.3.3 (p. 395), by default, lambdas may not
change their captured variables. As a result, by default, the function-call operator in a
class generated from a lambda is a const member function. If the lambda is declared
as mutable, then the call operator is not const.
www.it-ebooks.info
C++ Primer, Fifth Edition
We can rewrite the call to stable_sort to use this class instead of the lambda
expression:
Click here to view code image
stable_sort(words.begin(), words.end(), ShorterString());
The third argument is a newly constructed ShorterString object. The code in
stable_sort will “call” this object each time it compares two strings. When the
object is called, it will execute the body of its call operator, returning true if the first
string’s size is less than the second’s.
Classes Representing Lambdas with Captures
As we’ve seen, when a lambda captures a variable by reference, it is up to the
program to ensure that the variable to which the reference refers exists when the
lambda is executed (§ 10.3.3, p. 393). Therefore, the compiler is permitted to use the
reference directly without storing that reference as a data member in the generated
class.
In contrast, variables that are captured by value are copied into the lambda (§
10.3.3, p. 392). As a result, classes generated from lambdas that capture variables by
value have data members corresponding to each such variable. These classes also
have a constructor to initialize these data members from the value of the captured
variables. As an example, in § 10.3.2 (p. 390), the lambda that we used to find the
first string whose length was greater than or equal to a given bound:
Click here to view code image
// get an iterator to the first element whose size() is >= sz
auto wc = find_if(words.begin(), words.end(),
[sz](const string &a)
would generate a class that looks something like
Click here to view code image
class SizeComp {
SizeComp(size_t n): sz(n) { } // parameter for each captured
variable
// call operator with the same return type, parameters, and body as the lambda
bool operator()(const string &s) const
{ return s.size() >= sz; }
private:
size_t sz; // a data member for each variable captured by value
};
Unlike our ShorterString class, this class has a data member and a constructor to
initialize that member. This synthesized class does not have a default constructor; to
use this class, we must pass an argument:
www.it-ebooks.info
Documents you may be interested
Documents you may be interested