- •Table of Contents
- •Introduction
- •What Is C++?
- •Conventions Used in This Book
- •How This Book Is Organized
- •Part I: Introduction to C++ Programming
- •Part III: Introduction to Classes
- •Part IV: Inheritance
- •Part V: Optional Features
- •Part VI: The Part of Tens
- •Icons Used in This Book
- •Where to Go from Here
- •Grasping C++ Concepts
- •How do I program?
- •Installing Dev-C++
- •Setting the options
- •Creating Your First C++ Program
- •Entering the C++ code
- •Building your program
- •Executing Your Program
- •Dev-C++ is not Windows
- •Dev-C++ help
- •Reviewing the Annotated Program
- •Examining the framework for all C++ programs
- •Clarifying source code with comments
- •Basing programs on C++ statements
- •Writing declarations
- •Generating output
- •Calculating Expressions
- •Storing the results of expression
- •Declaring Variables
- •Declaring Different Types of Variables
- •Reviewing the limitations of integers in C++
- •Solving the truncation problem
- •Looking at the limits of floating-point numbers
- •Declaring Variable Types
- •Types of constants
- •Special characters
- •Are These Calculations Really Logical?
- •Mixed Mode Expressions
- •Performing Simple Binary Arithmetic
- •Decomposing Expressions
- •Determining the Order of Operations
- •Performing Unary Operations
- •Using Assignment Operators
- •Why Mess with Logical Operations?
- •Using the Simple Logical Operators
- •Storing logical values
- •Using logical int variables
- •Be careful performing logical operations on floating-point variables
- •Expressing Binary Numbers
- •The decimal number system
- •Other number systems
- •The binary number system
- •Performing Bitwise Logical Operations
- •The single bit operators
- •Using the bitwise operators
- •A simple test
- •Do something logical with logical calculations
- •Controlling Program Flow with the Branch Commands
- •Executing Loops in a Program
- •Looping while a condition is true
- •Using the for loop
- •Avoiding the dreaded infinite loop
- •Applying special loop controls
- •Nesting Control Commands
- •Switching to a Different Subject?
- •Writing and Using a Function
- •Divide and conquer
- •Understanding the Details of Functions
- •Understanding simple functions
- •Understanding functions with arguments
- •Overloading Function Names
- •Defining Function Prototypes
- •Variable Storage Types
- •Including Include Files
- •Considering the Need for Arrays
- •Using an array
- •Initializing an array
- •Accessing too far into an array
- •Using arrays
- •Defining and using arrays of arrays
- •Using Arrays of Characters
- •Creating an array of characters
- •Creating a string of characters
- •Manipulating Strings with Character
- •String-ing Along Variables
- •Variable Size
- •Address Operators
- •Using Pointer Variables
- •Comparing pointers and houses
- •Using different types of pointers
- •Passing Pointers to Functions
- •Passing by value
- •Passing pointer values
- •Passing by reference
- •Limiting scope
- •Examining the scope problem
- •Providing a solution using the heap
- •Defining Operations on Pointer Variables
- •Re-examining arrays in light of pointer variables
- •Applying operators to the address of an array
- •Expanding pointer operations to a string
- •Justifying pointer-based string manipulation
- •Applying operators to pointer types other than char
- •Contrasting a pointer with an array
- •Declaring and Using Arrays of Pointers
- •Utilizing arrays of character strings
- •Identifying Types of Errors
- •Choosing the WRITE Technique for the Problem
- •Catching bug #1
- •Catching bug #2
- •Calling for the Debugger
- •Defining the debugger
- •Finding commonalities among us
- •Running a test program
- •Single-stepping through a program
- •Abstracting Microwave Ovens
- •Preparing functional nachos
- •Preparing object-oriented nachos
- •Classifying Microwave Ovens
- •Why Classify?
- •Introducing the Class
- •The Format of a Class
- •Accessing the Members of a Class
- •Activating Our Objects
- •Simulating real-world objects
- •Why bother with member functions?
- •Adding a Member Function
- •Creating a member function
- •Naming class members
- •Calling a Member Function
- •Accessing a member function
- •Accessing other members from a member function
- •Defining a Member Function in the Class
- •Keeping a Member Function After Class
- •Overloading Member Functions
- •Defining Arrays of and Pointers to Simple Things
- •Declaring Arrays of Objects
- •Declaring Pointers to Objects
- •Dereferencing an object pointer
- •Pointing toward arrow pointers
- •Passing Objects to Functions
- •Calling a function with an object value
- •Calling a function with an object pointer
- •Calling a function by using the reference operator
- •Returning to the Heap
- •Comparing Pointers to References
- •Linking Up with Linked Lists
- •Performing other operations on a linked list
- •Hooking up with a LinkedListData program
- •A Ray of Hope: A List of Containers Linked to the C++ Library
- •Protecting Members
- •Why you need protected members
- •Discovering how protected members work
- •Protecting the internal state of the class
- •Using a class with a limited interface
- •Creating Objects
- •Using Constructors
- •Why you need constructors
- •Making constructors work
- •Dissecting a Destructor
- •Why you need the destructor
- •Working with destructors
- •Outfitting Constructors with Arguments
- •Justifying constructors
- •Using a constructor
- •Defaulting Default Constructors
- •Constructing Class Members
- •Constructing a complex data member
- •Constructing a constant data member
- •Constructing the Order of Construction
- •Local objects construct in order
- •Static objects construct only once
- •Global objects construct in no particular order
- •Members construct in the order in which they are declared
- •Destructors destruct in the reverse order of the constructors
- •Copying an Object
- •Why you need the copy constructor
- •Using the copy constructor
- •The Automatic Copy Constructor
- •Creating Shallow Copies versus Deep Copies
- •Avoiding temporaries, permanently
- •Defining a Static Member
- •Why you need static members
- •Using static members
- •Referencing static data members
- •Uses for static data members
- •Declaring Static Member Functions
- •What Is This About, Anyway?
- •Do I Need My Inheritance?
- •How Does a Class Inherit?
- •Using a subclass
- •Constructing a subclass
- •Destructing a subclass
- •Having a HAS_A Relationship
- •Why You Need Polymorphism
- •How Polymorphism Works
- •When Is a Virtual Function Not?
- •Considering Virtual Considerations
- •Factoring
- •Implementing Abstract Classes
- •Describing the abstract class concept
- •Making an honest class out of an abstract class
- •Passing abstract classes
- •Factoring C++ Source Code
- •Defining a namespace
- •Implementing Student
- •Implementing an application
- •Project file
- •Creating a project file under Dev-C++
- •Comparing Operators with Functions
- •Inserting a New Operator
- •Overloading the Assignment Operator
- •Protecting the Escape Hatch
- •How Stream I/O Works
- •The fstream Subclasses
- •Reading Directly from a Stream
- •Using the strstream Subclasses
- •Manipulating Manipulators
- •Justifying a New Error Mechanism?
- •Examining the Exception Mechanism
- •What Kinds of Things Can I Throw?
- •Adding Virtual Inheritance
- •Voicing a Contrary Opinion
- •Generalizing a Function into a Template
- •Template Classes
- •Do I Really Need Template Classes?
- •Tips for Using Templates
- •The string Container
- •The list Containers
- •Iterators
- •Using Maps
- •Enabling All Warnings and Error Messages
- •Insisting on Clean Compiles
- •Limiting the Visibility
- •Avoid Overloading Operators
- •Heap Handling
- •Using Exceptions to Handle Errors
- •Avoiding Multiple Inheritance
- •Customize Editor Settings to Your Taste
- •Highlight Matching Braces/Parentheses
- •Enable Exception Handling
- •Include Debugging Information (Sometimes)
- •Create a Project File
- •Customize the Help Menu
- •Reset Breakpoints after Editing the File
- •Avoid Illegal Filenames
- •Include #include Files in Your Project
- •Executing the Profiler
- •System Requirements
- •Using the CD with Microsoft Windows
- •Using the CD with Linux
- •Development tools
- •Program source code
- •Index
Chapter 6: Creating Functions |
83 |
Enter next number: 3
Enter next number: -1
The total is 6
Enter next sequence
Enter next number: 1
Enter next number: 2
Enter next number: -1
The total is 3
Enter next sequence
Enter next number: -1
Thank you
Press any key to continue . . .
Understanding the Details of Functions
Functions are so fundamental to creating C++ programs that getting a handle on the details of defining, creating, and testing them is critical. Armed with the example FunctionDemo program, consider the following definition of function:
A function is a logically separated block of C++ code. The function construct has the following form:
<return type> name(<arguments to the function>)
{
// ...
return <expression>;
}
The arguments to a function are values that can be passed to the function to be used as input information. The return value is a value that the function returns. For example, in the call to the function square(10), the value 10 is an argument to the function square(). The returned value is 100.
Both the arguments and the return value are optional. If either is absent, the keyword void is used instead. That is, if a function has a void argument list, the function does not take any arguments when called (this was the case with the FunctionDemo program). If the return type is void, the function does not return a value to the caller.
In the example FunctionDemo program, the name of the function is sumSequence(), the return type is int, and no arguments exist.
84 |
Part II: Becoming a Functional C++ Programmer |
The default argument type to a function is void, meaning that it takes no arguments. A function int fn(void) may be declared as int fn().
The function construct made it possible for me to write two distinct parts of the FunctionDemo program separately. I concentrated on creating the sum of a sequence of numbers when writing the sumSequence() function. I didn’t think about other code that may call the function.
Similarly, when writing main(), I concentrated on handling the summation returned by sumSequence() while thinking only of what the function did — not how it worked.
Understanding simple functions
The simple function sumSequence() returns an integer value that it calcu lates. Functions may return any of the regular types of variables. For exam ple, a function might return a double or a char (int, double, and char are a few of the variable types discussed in Chapter 2).
If a function returns no value, the return type of the function is labeled void.
A function may be labeled by its return type — for example, a function that returns an int is often known as an integer function. A function that returns no value is known as a void function.
For example, the following void function performs an operation, but returns no value:
void echoSquare()
{
int value;
cout << “Enter a value:”;
cin >> value;
cout << “\n The square is:” << (value * value) << “\n”; return;
}
Control begins at the open brace and continues through to the return state ment. The return statement in a void function is not followed by a value.
The return statement in a void function is optional. If it isn’t present, execu tion returns to the calling function when control encounters the close brace.
Chapter 6: Creating Functions |
85 |
Understanding functions with arguments
Simple functions are of limited use because the communication from such functions is one-way — through the return value. Two-way communication is through function arguments.
Functions with arguments
A function argument is a variable whose value is passed to the calling function during the call operation. The following SquareDemo example program defines and uses a function square() that returns the square of a double precision float passed to it:
//SquareDemo - demonstrate the use of a function
//which processes arguments
#include <cstdio> #include <cstdlib> #include <iostream> using namespace std;
//square - returns the square of its argument
//doubleVar - the value to be squared
//returns - square of doubleVar double square(double doubleVar)
{
return doubleVar * doubleVar;
}
//sumSequence - accumulate the square of the number
// |
entered at the keyboard into a sequence |
// |
until the user enters a negative number |
double sumSequence(void) |
|
{ |
|
// loop forever |
|
double accumulator= 0.0; |
|
for(;;) |
|
{ |
|
// fetch another number |
|
double dValue = 0; |
|
cout << “Enter next number: “; |
|
cin |
>> dValue; |
// if it’s negative... |
if (dValue < 0)
{
// ...then exit from the loop
86 |
Part II: Becoming a Functional C++ Programmer |
break;
}
//...otherwise calculate the square double value = square(dValue);
//now add the square to the
//accumulator
accumulator= accumulator + value;
}
// return the accumulated value return accumulator;
}
int main(int nNumberofArgs, char* pszArgs[])
{
cout << “This program sums multiple series\n”
<<“of numbers squared. Terminate each sequence\n”
<<“by entering a negative number.\n”
<<“Terminate the series by entering two\n”
<<“negative numbers in a row\n”
<<endl;
//Continue to accumulate numbers...
double accumulatedValue; for(;;)
{
//sum a sequence of numbers entered from
//the keyboard
cout << “Enter next sequence” << endl; accumulatedValue = sumSequence();
//terminate if the sequence is zero or negative if (accumulatedValue <= 0.0)
{
break;
}
//now output the accumulated result
cout << “\nThe total of the values squared is “
<<accumulatedValue
<<endl;
}
cout << “Thank you” << endl;
//wait until user is ready before terminating program
//to allow the user to see the program results system(“PAUSE”);
return 0;
}