Reference Materials

 

C++

 

 

Document filename:

TTI Documentation-C++ Referrence.doc

Version:

000.02

Issue date:

21-Mar-25

Document custodian:

Marc Narder

Phone:

07 54775202

Custodian e-mail:

This email address is being protected from spambots. You need JavaScript enabled to view it.

 

 

 

 

DRAFT

 

 

The material in this publication has been prepared by, and for the guidance and use of employees of the Teseract Technologies International.  These contents are not to be made public without prior authorisation.

 

Copyright

Copyright © the State of Queensland 1997

Document control

Copies of this document and any subsequent revisions shall be distributed electronically.

With the exception of a single, signed hard copy maintained by the Document Custodian, hard copies of this document are deemed uncontrolled.

Approval

 

 

 

 

 

1

Managing Director

Marc Narder

 

Date

 

 

1     Syntax Overview

C++ is Case Sensitive

1.1    Conditional Processing

1.1.1   If

if (tested condition is satisfied) {

  block of code

}

 else {

   block of code

 }

1.1.2   Switch

switch (variable) {

    case expression1:

        do something 1;

        break;

    case expression2:

        do something 2;

        break;

      ....

    default:

        do default processing;

}

1.1.3   Summary of Relational Operators

==       equal           

!=        not equal

>         greater than

>=       greater than or equal

<         less than

<=       less than or equal

1.1.4   Summary of Comparison Operators

&&      AND  

||         OR               

!          NOT

 

1.2    Statements

1.2.1   Constants

Const pi = 3.141592654

1.2.2   Enumerations

enum COLOR { RED, BLUE, GREEN};

1.2.3   Define

Define a constant or a pre-processor Macro

#Define

1.2.4   Include

Include the source code from another C== file in this assembly

#Include

1.2.5   Using

Uses the namespace from the Include

Using std

1.2.6   Main

Every Program must have a main function

Int is the Return Value

int Main()

{

Return 0

}

1.2.6.1     

 

1.3    Looping

1.3.1   WhileDo Loops

while (tested condition is satisfied) {

    block of code

}

1.3.2   DoWhile Loops

do {

    block of code

} while (condition is satisfied)

1.3.3   For Loops

for (initializations;test conditions;actions)

{

    block of code

}

E.G.

for (int count = 1; count <= 10; count++)

{

    cout << count << endl;

}

1.4    Data Structures

1.4.1   Pointers

int *ptr;

ptr = &count    // Stores the address of count in ptr

    // The unary operator & returns the address of a variable 

E.G.

int total;

total = *ptr;

   // The value in the address stored in ptr is assigned to total 

 

 

*pt1 =*pt1 + 2; 

This adds two to the value "pointer to" by pt1. That is, this statement adds 2 to the contents of the memory address contained in the pointer pt1. So, from the main program, pt1 contains the address of j. The variable "j" was initialized to 1. The effect of the above statement is to add 2 to j.

The contents of the address contained in a pointer may be assigned to another pointer or to a variable.

*pt2 = *pt1;

    // Assigns the contents of the memory pointed to by pt1

    // to the contents of the memory pointer to by pt2;

k = *pt2;

    // Assigns the contents of the address pointer to by pt2 to k. 

 

1.4.2   Pointer Arithmetic

Part of the power of pointers comes from the ability to perform arithmetic on the pointers themselves. Pointers can be incremented, decremented and manipulated using arithmetic expressions. Recall the float pointer "pt3" and the float array "values" declared above in the main program.

pt3 = &values[0];

    // The address of the first element of "values" is stored in pt3

pt3++;

    // pt3 now contains the address of the second element of values

*pt3 = 3.1415927;

    // The second element of values now has pie (actually pi)

pt3 += 25;

    // pt3 now points to the 27th element of values

*pt3 = 2.22222;

    // The 27th element of values is now 2.22222

 

pt3 = values;

    // pt3 points to the start of values, now

 

for (ii = 0; ii < 100; ii++)

{

     *pt3++ = 37.0;    // This sets the entire array to 37.0

}

 

pt3 = &values[0];

    // pt3 contains the address of the first element of values

pt4 = &results[0];

    // pt4 contains the address of the first element of results

 

for (ii=0; ii < 100; ii++)

{

     *pt4 = *pt3;

            // The contents of the address contained in pt3 are assigned to

            // the contents of the address contained in pt4

     pt4++;

     pt3++;

}

 

 

2     Classes

2.1    Class Structure

This simple example illustrates several important concepts. First, the keyword private indicates that the two members, age and weight, cannot be directly accessed from outside of the class. The keyword public indicates that the methods, setAge, getAge, setWeight, getWeight and speak, can be called from code outside of the class. That is, they may be called by other parts of a program using objects of this class. This technique of allowing access and manipulation of data members only through methods is referred to as data hiding. The interface to the class is public and the data is private. Public interface, private data is a key concept when designing classes. Data hiding will be discussed more in a later section of this article. Also, note that four of the methods, setAge, getAge, setWeight and getWeight, are involve reading or updating members of the class. Methods used to set or get members are called accessor methods or accessors.

#include <iostream>
using namespace std;

class Dog {
private:
    int age;
    int weight;
public:
    Dog();      //Constructor
    ~Dog();    //Destructor
    void setAge(int age);
    int getAge();
    void setWeight(int weight);
    int getWeight();
    void speak();
};

Dog::Dog()
{
    age = 0;
    weight = 0;
    cout << "Dog Constructor Called" << endl;
}

Dog::~Dog()
{
    cout << "Dog Destructor Called" << endl;
}

void Dog::setAge(int age)
{
    this->age = age;
}

int Dog::getAge()
{
    return age;
}

void Dog::setWeight(int weight)
{
    this->weight = weight;
}

int Dog::getWeight()
{
    return weight;
}

void Dog::speak()
{
    cout << "BARK!!" << endl;
}

int main()
{
    Dog fido;
    Dog rover;

    cout << "Rover is " << rover.getAge() << " years old." << endl;
    cout << "He weighs " << rover.getWeight() << " lbs." << endl;
    cout << endl;

    cout << "Updating Rover's Age and Weight" << endl;
    rover.setAge(1);
    rover.setWeight(10);

    cout << "Rover is " << rover.getAge() << " years old." << endl;
    cout << "He weighs " << rover.getWeight() << " lbs." << endl;
    cout << endl;

    cout << "Fido is " << fido.getAge() << " years old." << endl;
    cout << "He weighs " << fido.getWeight() << " lbs." << endl;

    cout << "Setting Fido to be the same as Rover" << endl;
    fido = rover;

    cout << "Fido is " << fido.getAge() << " years old." << endl;
    cout << "He weighs " << fido.getWeight() << " lbs." << endl;

    rover.speak();
    fido.speak();

    return 0;
}

There are a few important things to notice here. First, since the methods are implemented outside of the class definition, they must be identified as belonging to that class. This is done with the scope resolution operator, "::". It identifies each method, for example, getAge, as belonging to the class Dog. Second, every object has a special pointer call "this", which refers to the object itself. So the members of the Dog class can be referred to as this->age or this->weight, as well as, age or weight. If there is no ambiguity, no qualification is required. So in the getWeight method, "weight" can be used instead of "this->weight". In the setWeight method an ambiguity exists. Since the parameter passed is "weight" and there is a class member "weight", the "this" pointer must be used. Finally, a note about syntax. If "this" is a pointer to a class, then the member selection operator, "->", can be used to access the contents of its members.

Constructors and DestructorsEach class also has a special method, the constructor, that is called when an object of the class is instantiated (created). The constructor can be used to initialize variables, dynamically allocate memory or setup any needed resources. Another special method, the destructor, is called when an object is destroyed. An object is destroyed when it goes out of scope. If an object is created within a function, it will go out of scope when the function exits. Since your program is the "main" function, all its objects go out of scope when the program ends. Scope is described fully in a later lesson. The destructor is used to free any memory that was allocated and possible release other resources. Here is the Dog class with a constructor and a destructor added. Since they are given on the last page, the implementations of all member functions are not reproduced here.

it is possible to have multiple constructors that differ in their number and/or type of parameters. The constructor that is used is based on the arguments used in its invocation. This is referred to as function or method overloading.

 

3     Data Structure

3.1    Arrays

An array is defined with this syntax.

datatype arrayName[size][Size2] … = {value,Value…};

E.G.

datatype arrayName[size];

 

int ID[30];
              /* Could be used to store the ID numbers of students in a class */

float temperatures[31];
              /* Could be used to store the daily temperatures in a month */

char name[20];
              /* Could be used to store a character string. C-style character strings are terminated be the null character, '\0'. This will be discussed in a later lesson. */

int *ptrs[10];
              /* An array holding 10 pointers to integer data */

unsigned short int[52];
              /* Holds 52 unsigned short integer values */

class POINT {
public:
    POINT() { x = 0; y = 0;}
    ~POINT();
    //Accessor methods declared here
private:
    int x;
    int y;
}

POINT dots[100];

3.2    Vectors

#include <vector>

A vector of integers is defined as follows:

vector<int> scores(50);
        //Defines a vector of 50 ints

The vector class is a template. The C++ language allows classes and functions to be declared as templates. Templates allow data types to be parameterized in the class or function definitions. This will be explained fully in later lessons. For now, all that is needed is to think of templates as a way to allow a class or function to work with different data types. For instance a vector of floats can be defined as:

vector<float> amounts(50);
        //Defines a vector of 50 floats

The template allows the same class, vector in this case, to be used with many different data types, including programmer defined classes.

Class Dog {...}

vector<Dog> dogs(99);
        // Defines a vector of 99 dogs

Note that if templates were not part of the language, a separate "vector" class would be needed for each data type. There would be a "vectori" for ints, "vectorf" for floats and "bark" for dogs. For a user defined type to be used in a vector there are three additional requirements that must be satisfied. The type must supply a default value. For classes, this is the default constructor. The type must support the equality operator. For classes, this is an overloaded operator. This will be discussed in later lessons. The type must support the less-than operator. Again, this is an overloaded operator for classes. Built-in data numeric and pointer data types such as int and float get initialized to zero when a vector is defined. A vector of classes is initialized by its default constructor. In contrast, arrays are not initialized be default in C++. Arrays should be explicitly initialized by the programmer with either code or an initialization list in the array definition.

3.2.1   Vector Methods

at(size_type index)

Returns a reference to the element at the location specified.

back()

Returns a reference to the element at the end of the vector.

begin()

Returns an iterator to the start of the vector.

clear()

Erases the vector.

empty()

Returns true if the vector is empty.

end()

Returns an iterator one past the end of the vector.

erase(iterator where)
erase(iterator first, iterator last)

Removes a single element or range of elements.

front()

Returns a reference to the first element of the vector.

insert(iterator where, const type &val)
insert(iterator where, size_type number, const type &val)
insert(iterator where, iterator input_begin, iterator input_end)

Inserts a value or values into a vector at the specified position(s).

pop_back()

Deletes the element at the end of the vector. (Compare with back)

push_back(const type &val)

Adds an element to the end of the vector.

size()

Returns the number of elements in the vector.

==, !=

Returns true or false.

<, <=, >, >=

Returns true or false

=

Assigns one vector to another

4     String Class

4.1    Methods

The string class has many methods for string manipulations such as appending, inserting, deleting, searching and replacing. Some of the more common methods are summarized in the following table. Please consult other references such as your IDE's help facility, man pages or other references for a full listing.

Method

Use

append(char *pt);
append(char *pt, size_t count);
append(string &str, size_t offset,size_t count);
append(string &str);
append(size_t count, char ch);
append(InputIterator Start, InputIterator End);

Appends characters to a string from C-style strings, char's or other string objects.

at(size_t offset);

Returns a reference to the character at the specified position. Differs from the subscript operator, [], in that bounds are checked.

begin();

Returns an iterator to the start of the string.

*c_str();

Returns a pointer to C-style string version of the contents of the string.

clear();

Erases the entire string.

copy(char *cstring, size_t count, size_t offset);

Copies "count" characters from a C-style string starting at offset.

empty();

Test whether a string is empty.

end();

Returns an iterator to one past the end of the string.

erase(iterator first, iterator last);
erase(iterator it);
erase(size_t pos, size_t count);

Erases characters from the specified positions.

find(char ch,size_t offset = 0);
find(char *pt,size_t offset = 0);
find(string &str,size_t offset = 0);

Returns the index of the first character of the substring when found. Otherwise, the special value "npos" is returned.

find_first_not_of();

Same sets of arguments as find. Finds the index of the first character that is not in the search string.

find_first_of();

Same sets of arguments as find. Finds the index of the first character that is in the search string.

find_last_not_of();

Same sets of arguments as find. Finds the index of the last character that is not in the search string.

find_last_of();

Same sets of arguments as find. Finds the index of the last character that is in the search string.

insert(size_t pos, char *ptr);
insert(size_t pos, string &str);
insert(size_t pos, size_t count, char ch);
insert(iterator it, InputIterator start, InputIterator end);

Inserts characters at the specified position.

push_back(char ch);

Inserts a character at the end of the string.

replace(size_t pos, size_t count, char *pt);
replace(size_t pos, size_t count, string &str);
replace(iterator first, iterator last, char *pt);
replace(iterator first, iterator last, string &str);

Replaces elements in a string with the specified characters. The range can be specified by a start position and a number of elements to replace, or by using iterators.

size();

Returns the number of elements in a string.

swap(string &str);

Swaps two strings.

4.2    String Class

4.2.1   Methods

#include <iostream>

#include <string>

using namespace std;

 

int main()

{

    string S1("Hello World");

    string S2("from About");

    string S3("Bye");

    char c1[] = "Universe";

    size_t index;

 

    cout << S1 << endl;

    index = S1.find('W');

        // Returns an iterator to W in World

    S1.erase(index,1);

        // S1 is now "Hello orld"

    cout << S1 << endl;

 

    string::iterator begin = S1.begin() + S1.find_last_of('o');

    string::iterator end = S1.end();

    S1.erase(begin,end);

        // Erases "orld"

    cout << S1 << endl;

 

    S1.append(c1);

        // Appends "Universe"

    cout << S1 << endl;

 

    S1.clear();

        // Clears S1;

    if (S1.empty())

    {

        cout << "S1 has been cleared" << endl;

        cout << "Its size is " << S1.size() << endl;

    }

 

    S1.push_back('H');    //H is a char

    S1.insert(1,"ello");    //"ello" is a C-style string.

    cout << S1 << endl;

 

    S1 += ' ';    //Add a space

    S1 += S2;    // Concatenate S1 and S2

    cout << S1 << endl;

 

    begin = S1.begin() + S1.find("About");

    end = S1.end();

    S1.replace(begin,end,"John");

    cout << S1 << endl;

 

    S1.swap(S3);

    cout << S1 << endl;

 

    return 0;

}

 

 

5     File Input Output

·        By default, if a file does not exist it is created.

·        By default, a file will be a text file, not a binary file.

·        By default, an existing file is truncated.

·        To combine modes, "or" them together using "|".

Mode

Meaning

out

Open a file or stream for insertion (output).

In

Open a file or stream for extraction (input).

app

Append rather than truncate an existing file. Each insertion (output) will be written to the end of the file

trunc

Truncate existing file (default behavior)

ate

Opens the file without truncating, but allows data to be written anywhere in the file

binary

Treat the file as binary rather than text. A binary file has data stored in internal formats, rather than readable text format. For example, a float would be stored as its internal four byte representation rather than as a string.

To open a file, truncating any existing contents, use any of the three equivalent statements.

ofstream myFile("SomeFileName");
ofstream myFile("SomeFileName",ios::out);
ofstream myFile("SomeFileName",ios::out | ios::trunc);

To open a file, and append to any previous contents:

ofstream myFile("SomeFileName",ios::app);

To open a file for binary output:

ofstream myFile("SomeFileName",ios::binary);

To open a file for input, an object of ifstream class is used:

ifstream inFile("SomeFileNale");

5.1    Useful Methods of Input and Output Classes

The ifstream class has several useful methods for input. These method are also in the class cin, which is used to read from standard input. These methods are used to read from any input stream. An input stream is a source of input such as the keyboard, a file or a buffer.

5.1.1   Extraction Operator, >>

This overloaded operator handles all built in C++ data types. By default, any intervening white space is disregarded. That is, blanks, tabs, new lines, formfeeds and carriage returns are skipped over.

5.1.2   get()

This form of get extracts a single character from the input stream, that is, from the standard input, a file or a buffer. It does not skip white space. It returns type int.

5.1.3   get(char &ch)

This form of get also extracts a single character from the input stream, but it stores the value in the character variable passed in as an argument.

5.1.4   get(char *buff, int buffsize, char delimiter='\n')

This form of get reads characters into the C-style buffer passed as an argument buffsize characters are read, the delimiter is encountered or an end of file is encountered. The '\n' is the new line character. The delimiter is not read into the buffer but is instead left in the input stream. It must be removed separately but using either another get or an ignore. Because of this added step, this form of get is a frequent source of errors and should be avoided. Fortunately, another method shown below, getline, reads in the delimiter as well and should be used in place of this form of get.

5.1.5   Getline

There are several useful forms of getline. Please look at this article for details. C++ Programming Tips- Tips on Input

5.1.6   ignore(int count=1, int delim=traits_type::eof)

This method reads and discards "count" characters from the input stream.

5.1.7   peek()

This method returns the next character from the input stream, but does not remove it. It is useful to look ahead at what the next character read will be.

5.1.8   putback(char &ch)

This method puts ch onto the input stream. The character in ch will then be the next character read from the input stream.

5.1.9   unget()

This method puts the last read character back into the input stream.

5.1.10  read(char *buff, int count)

This method is used to perform an unformatted read of count bytes from the input stream into a character buffer.

The ofstream class has several useful methods for writing to an output stream. An output stream is standard output (usually the screen), a file or a buffer. These methods are also in the object cout, which is used for standard output.

5.1.11  Insertion Operator, <<

This overloaded operator will handle all built-in C++ data types.

5.1.12  put(char ch)

This method puts a single character into the output stream.

5.1.13  write(char *buff, int count)

This method is used to perform an unformatted write from a character buffer to the output stream.

 

6     Functions

6.1    Declaring Functions

A function is declared with a prototype. A function prototype consists of the return type, a function name and a parameter list. The function prototype is also called the function declaration. Here are some examples of prototypes.

return_type function_name(list of parameters);

int max(int n1, int n2);    
int printResults(string buffer, int status);    

The function definition consist of the prototype and a function body, which is a block of code enclosed in parenthesis. A declaration or prototype is a way of telling the compiler the data types of the any return value and of any parameters, so it can perform error checking. The definition creates the actual function in memory. Here are some examples of functions.

6.2    Returning Multiple Values from Functions and Methods

So far, all the examples shown have either not returned any values, or have returned a single value using the return statement. In practice, it will be common to need to return multiple values from a function. Let's see how this can be done by developing a function to swap two integer values. Here's a first attempt.

#include <iostream>
using namespace std

void swap(int x, int y);
        /* Note that the variable names in the
           prototype and function
           definition need not match.
           Only the types and number of
           variables must match */

int main()
{
    int x = 4;
    int y = 2;

    cout << "Before swap, x is " << x << ", y is " << y << endl;
    swap(x,y);
    cout << "After swap, x is " << x << ", y is " << y << endl;

}

void swap(int first, int second)
{
    int temp;

    temp = second;
    second = first;
    first = temp;
}

Results:



What happened? The values weren't swapped. The function didn't work as expected. The arguments were passed into the function by value. This means that the function received a local copy of the argument. Any modifications to the local copy do not change the original variable in the calling program.

C++ has two techniques that can be used if a variable is to be modified within a function, and the modified value is desired in the calling routine. The first is to pass a pointer to the variable to the function. The pointer can then be manipulated to change the value of the variable in the calling routine. It is interesting to note that the pointer itself is passed by value. The function cannot change the pointer itself since it gets a local copy of the pointer. However, the function can change the contents of memory, the variable, to which the pointer refers. The advantages of passing by referrence are that any changes to variables will be passed back to the calling routine and that multiple variables can be changed. Here is the same example with references being passed into the function.

#include <iostream>
using namespace std;

void swap(int &x, int &y);

int main()
{
    int x = 4;
    int y = 2;

    cout << "Before swap, x is " << x << ", y is " << y << endl;
    swap(x,y);
    cout << "After swap, x is " << x << ", y is " << y << endl;

}

void swap(int &first, int &second)
{
    int temp;

    temp = second;
    second = first;
    first = temp;
}

 

 

 

7     Revision History

Records of formal review shall be maintained for each approved version (integer value) listed below. The document Custodian shall maintain copies of each version listed below.

Version

Date

Edited by

Comments / Summary of Changes

This document is based on template IPS Report Component Specification.dot

000.01

13th Jun 198

Marc Narder

Version 000.01

000.02

17th August 2006

Marc Narder

Version 000.02

 

End of document