Hour 21. Using New Features of C++0x

The Next Version of C++

Since the C++ programming language was created by Bjarne Stroustrop in 1979, it has undergone several significant revisions.

In 1983, its name was changed from C for Classes to C++, and numerous features such as virtual functions, operator overloading, and references were added. Two years later, the first edition of Stroustrop’s book The C++ Programming Language was published, offering a full reference to a language that had not yet become an official standard.

In 1989, version 2.0 of C++ came out and included such features as multiple inheritance, static member functions, and abstract classes.

Nine years later, the C++ standards committee published the standardized version of the language, a version described informally as C++98.

As this book is written, work continues on the next version of C++. It was originally expected to be done in either 2008 or 2009, dates that gave it the nickname C++0x. (The 0x stands in for the final two numbers in the year.)

Although C++0x has yet to be published, over its long gestation period the leading C++ tools already have added some of its features. You can begin taking advantage of several significant improvements to the language today.

Null Pointer Constant

As you learned during Hour 10, “Creating Pointers,” it’s important when using pointers to make sure they always have a value. A pointer that is not initialized could be pointing to anything in memory. These wild pointers, as they are called, pose a security and stability risk to your programs.

To prevent this, pointers are assigned a null value when created. This can be done by using either 0 or NULL as the value:

int *pBuffer = 0;

int *pBuffer = NULL;

These are both accomplishing the same thing. NULL is a preprocessor macro that is converted to either 0 (an integer) or 0L (a long).

Setting null pointers in this manner works well in almost all circumstances, but it creates an ambiguity when a class relies on function overloading. Consider an overloaded function that takes either a character pointer or an integer as an argument:

void displayBuffer(char *);
void displayBuffer(int);

If this function is called with a null pointer, the displayBuffer(int) member function will be called, despite the fact that this is probably not what the programmer intended.

C++0x addresses this pointer problem with the addition of a new keyword, nullptr, that represents the value of a null pointer:

int *pBuffer = nullptr;

The constant 0 also remains valid as a null pointer value, for reasons of backward compatibility, but nullptr is preferred.

A nullptr value is not implicitly converted to integer types except for bool values. For Booleans, nullptr converts to the value false.

The Swapper program (Listing 21.1) gives one variable the value of another using a pointer.

Listing 21.1 The Full Text of Swapper.cpp


 1: #include <iostream>
 2:
 3: int main()
 4: {
 5:    int value1 = 12500;
 6:    int value2 = 1700;
 7:    int *pointer2 = nullptr;
 8:
 9:    // give pointer the address of value2
10:    pointer2 = &value2;
11:    // dereference the pointer and assign to value1
12:    value1 = *pointer2;
13:    pointer2 = 0;
14:
15:    std::cout << "value1 = " << value1 << " ";
16:
17:    return 0;
18: }


Run Swapper to produce the following output:

value1 = 1700

The pointer2 variable is initialized as a null pointer, then assigned the address of the value2 variable on line 10. This is dereferenced and stored in value1 (line 12), replacing its original value.


Watch Out!

Your compiler might fail with an error message such as “’nullptr’ was not declared in this scope.” This error indicates that your C++ development environment does not support the C++0x features described during this hour—or that you’re not compiling with these features turned on. The GNU Compiler Collection version 4.6.0 supports C++0x, as long as you compile with the command-line option -std=C++0x.

Even if your compiler doesn’t support these features, they should be simple enough to learn even without hands-on experience trying them out.


Compile-Time Constant Expressions

C++ compilers do everything they can to make programs run faster, optimizing the code that you’ve written wherever possible. One simple opportunity for increased efficiency is when two constants are added together, as in this sample code:

const int decade = 10;
int year = 2011 + decade;

Because both halves of the expression 2011 + decade are constants, compilers evaluate the expression and store it in compiled form as the result 2021. The compiler acts as if year were assigned the value 2021.

Functions can use the const keyword to return a constant value:

const int getCentury()
{
    return 100;
}

For this reason, you might think the following expression has the potential to be optimized:

int year = 2011 + getCentury();

Although the member function returns a constant, the function itself might not be constant. It might change global variables or call nonconstant member functions.

C++0x adds constant expressions to the language with the constexpr keyword:

constexpr int getCentury()
{
    return 100;
}

The constant expression must have a non-void return type and contain return expression as its contents. The expression returned only can contain literal values, calls to other constant expressions or variables that also have been defined with constexpr.

The following statement defines a variable to be constexpr:

const int century = 100;
constexpr year = 2011 + century;

The Circle program (Listing 21.2) makes use of a constant expression to represent the value of PI, using it to calculate the area of a circle based on a radius value entered by the user.

Listing 21.2 The Full Text of Circle.cpp


 1: #include <iostream>
 2:
 3:// get an approximate value of PI
 4: constexpr double getPi() {
 5:     return (double) 22 / 7;
 6: }
 7:
 8: int main()
 9: {
10:     float radius;
11:
12:     std::cout << "Enter the radius of the circle: ";
13:     std::cin >> radius;
14:
15:     // the area equals PI * the radius squared
16:     double area = getPi() * (radius * radius);
17:
18:     std::cout << " Circle's area: " << area << " ";
19:
20:     return 0;
21: }


Here’s sample output for the program for a radius of 11:

Enter the radius of the circle: 11

Circle's area: 380.286

C++ does not have a keyword for the value PI. A reasonable approximation of its value suitable for some uses is to divide 22 by 7. When stored as a double in C++ it equals 3.14286, the value of PI rounded to five places.

The Circle program calculates 22 / 7 as a constant expression. The function can do this because it contains only one statement, the return expression, and only includes literals, constants, or constant expressions.


Watch Out!

The constexpr keyword is not supported in Microsoft Visual Studio 10, so you can’t take advantage of the new feature if you’re doing C++ programming in that development environment. It should be available in the next version.


Auto-Typed Variables

One of the first things you learned about variables in C++ is that the size of built-in data types such as long and double can be different on different implementations. The sizeof() function tells you how many bytes a type occupies:

std::cout << "Integers require " << sizeof(int) << " bytes."

The new auto keyword in C++0x enables a type to be inferred based on the value that’s initially assigned to it. The compiler figures out the proper data type.

Here’s an example:

auto index = 3;
auto gpa = 2.25F;
auto rate = 500 / 3.0;

These statements create an index variable that holds an int value, a gpa variable that holds a float and a rate variable that holds a double. The literal assigned to the variables at initialization determines the type of the variable.

In the rate statement, the expression 500 / 3.0 produces a double because one of the operands is a double value.

This works with the return value of functions, as well:

auto score = calculateScore();

The return type of the function is the return type of the score variable.

auto is not a new data type in C++. The compiler determines the type and it’s as if the following statements were encountered:

int index = 3;
float gpa = 2.25F;
double rate = 500 / 3.0;

Because of how auto works, it’s not permitted to declare an auto-typed variable without assigning it a value at initialization.

There are a few limitations, as well. An array cannot use auto, and it cannot be used as a function’s parameter or return type. None of the following statements compile:

auto ages[]={9, 11, 15};
int check(auto x);
auto printFile(int copies);

The auto keyword cannot be used to define class member variables or in struct structures either, unless it is a static member.

Multiple variables can be assigned with an auto keyword as long as every one of the variables has the same data type.

auto a = 86, b = 75, c = 309;

The Combat program (Listing 21.3) calculates combat statistics such as those for a character in a videogame.

Listing 21.3 The Full Text of Combat.cpp


 1: #include <iostream>
 2:
 3: int main()
 4: {
 5:     // define character values
 6:     auto strength;
 7:     auto accuracy;
 8:     auto dexterity;
 9:
10:     // define constants
11:     const auto maximum = 50;
12:
13:     // get user input
14:     std::cout << " Enter strength (1-100): ";
15:     std::cin >> strength;
16:
17:     std::cout << " Enter accuracy (1-50): ";
18:     std::cin >> accuracy;
19:
20:     std::cout << " Enter dexterity (1-50): ";
21:     std::cin >> dexterity;
22:
23:     // calculate character combat stats
24:     auto attack = strength * (accuracy / maximum);
25:     auto damage = strength * (dexterity / maximum);
26:
27:     std::cout << " Attack rating: " << attack << " ";
28:     std::cout << "Damage rating: " << damage << " ";
29: }


This program displays output such as the following:

Enter strength (1-100): 80

Enter accuracy (1-50): 45.5

Enter dexterity (1-50): 24

Attack rating: 72.8
Damage rating: 38.4

In lines 14–21, the user is asked to enter three attributes: the character’s strength, accuracy, and dexterity. In lines 24–25, these are plugged in to formulas to calculate an attack rating and damage rating. If this code were part of a game, the values would be used when the character engages in combat.

All six variables in the program make use of the auto keyword, so if users enter integers they are treated as int variables. If users enter floating-point values, they’re treated as double.

Run the program several times with different types of numeric input to see how the answers change in numeric format.


Watch Out!

There already was an auto keyword in C++ prior to version C++0x. It was supposed to be used to indicate that a variable was local in scope. The developers of C++ inspected millions of lines of code and found only a handful of uses, most of which were in test suites. They decided the keyword was redundant and useless and replaced it with this new functionality.

Any code that relies on the old meaning of auto will not work in C++0x.


New for Loop

One disadvantage of C++ relative to languages such as Java is the amount of code required to do one of the most common tasks in programming. When you iterate through the elements of an array or another list, the code is verbose and inelegant.

C++0x adds a new for loop that’s much easier for this task.

The for statement has two sections separated by a colon (:). The first is a reference that holds the value of the list or list element. The second is the name of the list.

The following code multiplies every element of an array by 3 and displays the result:

int positions[5] = {4, 3, 10, 25, 8};
for (int &p: positions)
{
    p *= 3;
    std::cout << p << " ";
}

This is called a range-based for loop and can be used on arrays, initializer lists, and any class that has a begin() and end() function that return iterators.

Summary

The features introduced during this hour are just the first that have been implemented in compilers such as GCC (the GNU Compilers Collection).

C++0x will also include the following additions and improvements:

• The ability of constructors to call other constructors of that class

• A new return syntax for function templates

• Better virtual function overriding

• Unicode support for string literals

• User-defined literals

• The new built-in data type long long int

C++ creator Bjarne Stroustrop writes on his website that he’s enormously excited about the new release: “C++0x feels like a new language: The pieces just fit together better than they used to and I find a higher-level style of programming more natural than before and as efficient as ever.”

For more of his thoughts, visit his site at http://www2.research.att.com/~bs/C++0xFAQ.html.

Q&A

Q. Are there any risks to using the auto keyword?

A. One of the biggest is when you’re mistaken about what data type is being assigned by the statement. A common blunder in C++ is to assume that the literal 3.5 is a float literal. It’s actually a double. So if you’ve created an auto-typed variable using a value like that and you don’t realize it’s a double, you could make assumptions about how you can use the variable in a program.

Q. When will C++0x be finished?

A. At the time of this writing, C++0x has been published as a final committee draft and is supposed to be out at the end of 2011.

However, that estimate is coming from the same folks who once believed it would be done by 2008 or 2009. They’re clearly following the standards of the old Paul Masson wine commercial, “We will sell no wine before its time.”

The publication of the final committee draft meant that the C++ standards body was no longer considering new features, a big step toward the final release. But the group doing the work only meets three times a year for 6 days, so if a meeting does not reach agreement on issues, it pushes the process back another 4 months.

Although it’s possible C++0x will be a Christmas present in 2011, a more likely estimate is that it will be here by mid-2012.

Q. Who invented the crossword puzzle?

A. The crossword puzzle was devised by Arthur Wynne in 1913 for the New York World newspaper. The first one was published on December 21, 1913, and described as a “Word-Cross.”

Wynne created new puzzles each week for the newspaper. His puzzles had the same rules as current crossword puzzles but an unusual shape. Words crisscrossed each other on a diamond shaped grid with black squares in the middle.

Wynne quickly settled on a rectangular shape and the name “Cross-Word.” Eleven years later in 1924, fledgling book publishers Dick Simon and Lincoln Schuster introduced crosswords to an international audience by issuing a collection of New York World puzzles that became a bestseller.

The first crossword puzzle is available online at http://www.thinks.com/crosswords/first2.htm. If you can figure out a seven-letter word for “a written acknowledgment” that starts with R, I’d appreciate the help.

Workshop

Now that you’ve spent an hour on the future of C++, answer a few questions and undertake exercises to see how much knowledge you brought back to the present.

Quiz

1. Which of the following is not an acceptable place to use the auto keyword?

A. Initializing a variable with a literal

B. Initializing a variable with a function

C. Returning a value from a function

2. What types can a nullptr be converted to using casting?

A. int

B. bool

C. none

3. What can the constexpr keyword be used to define?

A. Functions

B. Variables

C. Functions and variables

Answers

1. C. The auto keyword can’t be used as the return value of a function or as a parameter to the parameter. The value returned by a function can be assigned with auto, because it has a non-auto return type.

2. B. The nullptr has the bool value of false after being cast, which C++0x supports because of existing code that relies on the behavior.

3. C. Any variable or function declared with constexpr is implicitly treated as a const.

Activities

1. Write a new version of the Circle program (Listing 21.2) that asks for a cylinder’s radius and height. Calculate its area as PI * radius2 * height.

2. Write a program with four overloaded square() functions that multiply a number by itself and take int, long, float, and double as their only parameter. Store the result of the function in an auto-typed variable and display it.

To see solutions to these activities, visit this book’s website at http://cplusplus.cadenhead.org.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.11.18