Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
51 views

Examples On Classes and Objects

The document discusses exception handling in C++. It covers throw, try, and catch keywords used to throw and catch exceptions. It provides an example PositiveInteger class that throws an invalid_argument exception if a negative value is passed. It also discusses creating custom exception subclasses by inheriting from the exception class or its subclasses like logic_error. Finally, it briefly mentions storage duration, scopes, and linkages as additional variable attributes.

Uploaded by

laure
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
51 views

Examples On Classes and Objects

The document discusses exception handling in C++. It covers throw, try, and catch keywords used to throw and catch exceptions. It provides an example PositiveInteger class that throws an invalid_argument exception if a negative value is passed. It also discusses creating custom exception subclasses by inheriting from the exception class or its subclasses like logic_error. Finally, it briefly mentions storage duration, scopes, and linkages as additional variable attributes.

Uploaded by

laure
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

yet another insignificant programming notes...

  |   HOME

TABLE OF CONTENTS (HIDE)


1.  Exception Handling

C++ Programming
1.1  throw, try and catch
1.2  Example: The Time Class
1.3  Class exception and its subcl
Language 1.4  Creating Your Own exception
2.  Storage Duration, Scopes and Li

Miscellaneous, Tips and 2.1  Automatic Local Variables ("au


2.2  Static Variables ("static" Spe

Traps 2.3  External Variables ("extern" S


2.4  Summary
2.5  CV-Qualifiers (const and vola
2.6  Function and Linkage
2.7  Other Scopes
3.  Summary of static Keyword
1.  Exception Handling 4.  Type Casting Operators
5.  Summary of const Keyword
C++ build the exception handling into the language via keyword
6.  C++ Keywords
throw, try and catch and headers <exception>, <stdexcept>.

In building your classes, you often need to validate the inputs in


member functions such as constructors and setters. In the case of
invalid inputs, instead of abnormally terminate the program (via abort() or exit()); or setting them to some
default values, it is better to throw an exception to the caller and let the caller decides what to do with the
exception.

1.1  throw, try and catch


Suppose that we have a class called PositiveInteger, which maintains a data member value containing a
positive integer.

PositiveInteger.h
1 /* Header for the PositiveInteger class (PositiveInteger.h) */
2 #ifndef POSITIVE_INTEGER_H
3 #define POSITIVE_INTEGER_H
4
5 class PositiveInteger {
6 private:
7 int value; // positive integer (>0) only
8
9 public:
10 PositiveInteger(int value = 1);
11 void setValue(int value);
12 int getValue() const;
13 };
14
15 #endif

PositiveInteger.cpp
1 /* Implementation for the PositiveInteger Class (PositiveInteger.cpp) */
2 #include <iostream>
3 #include <stdexcept> // Needed for exception handling
4 #include "PositiveInteger.h"
5 using namespace std;
6
7 // Constructor with input validation
8 PositiveInteger::PositiveInteger(int value) {
9 // Call setter to perform input validation
10 setValue(value);
11 }
12
13 // Setter with input validation
14 void PositiveInteger::setValue(int v) {
15 if (v > 0) {
16 value = v;
17 } else {
18 throw invalid_argument("value shall be more than 0.");
19 // need <stdexcept>
20 }
21 }
22
23 // Getter
24 int PositiveInteger::getValue() const {
25 return value;
26 }

Program Notes:
The constructor calls the setter setValue(), which validates the input value.

In setValue(), if the input is invalid, instead of print an error message or terminate the program (via
abort() or exit()), we throw an invalid_argument exception with an appropriate message. The
invalid_argument is one of the system-defined exception classes in header <stdexcept>.

TestPositiveInteger.cpp
1 /* Test Driver for the PositiveInteger class (TestPositiveInteger.cpp) */
2 #include <iostream>
3 #include <stdexcept> // Needed for exception handling
4 #include "PositiveInteger.h"
5 using namespace std;
6
7 int main() {
8 // Valid input
9 PositiveInteger i1(8);
10 cout << i1.getValue() << endl;
11
12 // Invalid input without try-catch
13 // PositiveInteger i2(-8); // Program terminate abruptly
14
15 // Graceful handling of exception with try-catch
16 try {
17 cout << "begin try 1..." << endl;
18 PositiveInteger i3(-8);
19 // Exception thrown.
20 // Skip the remaining statements in try and jump to catch.
21 cout << i3.getValue() << endl;
22 cout << "end try 1..." << endl;
23 // Continue to the next statement after try-catch, if there is no exception
24 } catch (invalid_argument & ex) { // need <stdexcept>
25 cout << "Exception: " << ex.what() << endl;
26 // Continue to the next statement after try-catch
27 }
28 cout << "after try-catch 1..." << endl;
29
30 // Graceful handling of exception with try-catch
31 try {
32 cout << "begin try 2..." << endl;
33 PositiveInteger i4(8); // no exception thrown
34 cout << i4.getValue() << endl;
35 cout << "end try 2..." << endl;
36 // Continue to the next statement after try-catch, if there is no exception
37 } catch (invalid_argument & ex) { // need <stdexcept>
38 cout << "Exception: " << ex.what() << endl;
39 // Continue to the next statement after try-catch
40 }
41 cout << "after try-catch 2..." << endl;
42 }

Program Notes:
Without the try-catch statement, the program abnormally terminated, when a throw statement is
encountered.
With try-catch, the execution skips the rest of the try-clause, when a throw statement is encountered. It
jumps into the catch-clause; and continues to the next statement after the try-catch. Take note that the
program is not abnormally terminated.
If no exception is encountered, the execution completes the try clause, skip the catch-clause, and
continues to the next statement after the try-catch.
The catch takes a parameter of a reference to exception class (in header <exception>) or its subclass
(such as invalid_argument in header <stdexcept>).
The exception class has a member function what(), which prints the exception message.
You can have multiple catch-clauses, each catching a exception type. If an exception is thrown, the catch-
clauses are matched in sequential manner. The catch clause catches an exception also catches its subclass.
If an exception is thrown, but no catch-clause matches the exception type. The program returns to its caller
(unwinding the function stack), and repeat the exception handling process in the caller.

1.2  Example: The Time Class


HERE.

1.3  Class exception and its subclasses


The root class is called exception (in header <exception>). It contains a member function what() which
returns the what-message:

virtual const char* what() const throw();


// what() is a virtual function, can be overridden by subclasses
// It returns a C-string.

Some commonly-used subclasses are pre-defined in header <stdexcept>:


1. logic_error: indicating programming logic errors, such as invalid_argument (invalid argument passed
into function), out_of_range (value, such as indexing subscript, out of range), length_error (length
larger than the maximum allowable length), etc.

class logic_error : public exception {


public:
explicit logic_error (const string & what_message);
};

2. runtime_error: indicating execution-time error, such as range_error (range error in internal


computation), overflow_error (result larger than the largest possible number), under_flow_error
(result smaller than the smallest possible number).
3. bad_exception: unexpected exception.

1.4  Creating Your Own exception subclass


You can create your own exception by subclassing exception or its subclasses (such as logic_error or
runtime_error). For example,

MyException.h
1 /* Header for the MyException class (MyException.h) */
2 #ifndef MY_EXCEPTION_H
3 #define MY_EXCEPTION_H
4
5 #include <stdexcept>
6
7 class MyException : public std::logic_error {
8 public:
9 // Constructor
10 MyException() : std::logic_error("my custom error") { };
11 };
12
13 #endif

Program Notes:
Your custom exception shall subclass exception or its subclass, in this case, logic_error.
Provide a constructor with a custom what-message.

TestMyException.cpp
1 /* Test Driver for the MyException class (TestMyException.cpp) */
2 #include <iostream>
3 #include "MyException.h"
4 using namespace std;
5
6 void fun() {
7 throw MyException();
8 }
9
10 int main() {
11 try {
12 fun();
13 } catch (MyException & ex) {
14 cout << ex.what() << endl;
15 }
16 }

2.  Storage Duration, Scopes and Linkages


Recall that a variable has a name, a type and stores a value of the particular type. It also have other attributes
such as storage duration, scope and linkage, which is either set implicitly, or via so-called storage class specifiers
such as auto (automatic storage allocation/deallocation. C++11 reassigns this keyword to mean automatic
derived type), register, static, extern, mutable and thread_local (added in C++11); or CV-qualifiers:
const and volatile (CV stands for constant-volatile).

Storage Duration - Automatic, Static and Dynamic


The storage duration (or storage class) determines the duration of a variable, i.e., when it is created and when it
is destroyed. They are 3 types of storage durations:
1. Automatic storage duration: Variables declared inside a function (including function parameters) or block
have automatic storage duration. They are created when the program enters the function (or the block) in
which they are defined, and destroyed (memory is deallocated and freed) when the program leaves the
function (or the block). They are called automatic as they are managed (created/destroyed) automatically
without programmer's explicit actions. They will be created/destroyed repeatably as the program enters
and leaves the function (or block).
2. Static storage duration: Variables declared outside all functions, or inside a function with static specifier
have static storage duration. The term static means that (a) the variable is created when the program
begins and destroyed when the program exits, i.e., it exists for the entire duration of the program; (b) the
variable retains its memory and contents throughout the entire execution.
3. Dynamic storage duration: Dynamic storage are managed by programmer explicitly (instead of
automatically). Storage (on the heap) is allocated via new operator and persists until they are freed via the
delete operator.

Compiler typically allocates 3 chunks of storage for static variables, automatic variables, and dynamically
allocated variables, respectively.
Scope - Local or Global
The scope of a variable determines which parts of the program can reference the variable, i.e., the visibility.
Some variables can be referenced throughout the program (file-scope or global-scope); while others can only
be referenced in a limited part of the program (block-scope or local-scope). For example, a local automatic
variable defined inside a function (or a block) is visible by that function (or block), and not outside the function
(or block).

There are two scopes:


1. A variable having local scope (or block scope) is visible only inside the block.
2. A variable having global scope (or file scope) is visible throughout the file.

Linkage - Internal or External


A C/C++ application may consist of many source files (or translational units). The linkage of a variable
determines how a variable is shared by different files. A variable with external linkage can be shared by other
source files; while a variable with internal linkage can only be used in the file that it is defined. That is, external
linkage extends the file-scope to other source files.

In summary, with linkage, there are 3 combinations of scopes/linkages:


1. block-scope (or local-scope) with no linkage,
2. file-scope (or global scope) with internal linkage,
3. file-scope (or global scope) with external linkage.

Take note that a variable might exist in memory (determined by its storage duration) but not visible by a certain
part of the program (determined by its scope and linkage). For examples, a local variable created within a
function still exists when the function calls another function, but it is not visible by the second function. A
static variable declared inside a function exists throughout the program duration, but visible only by that
function. A static variable with internal linkage exists throughout the program duration, but visible only to the
file in which it is defined.

2.1  Automatic Local Variables ("auto" Specifier)


Variables defined inside a function (block) and function parameters are "auto", by default. They have automatic
storage duration, i.e., they are created when the program enters the function (block) and destroyed when the
program leaves the function (block). They have local scope (i.e., can be used within the function or block
immediately after they are declared) and no linkage (i.e., either internal or external linkage).

Automatic storage is used to converse memory, as these variables does not exist throughout the entire
program, but created when needed (and destroyed).

You can use the auto specifier to explicitly specify automatic storage class for a variable. However, it is rarely
used as auto is the default for local variables. In C++11, the keyword "auto" is assigned a new meaning to
indicates automatic type deduction. The old meaning of automatic storage class is no longer valid in C++11.

For example,

1 /* Test Local Variable Duration and Scope (LocalVariableScope.cpp) */


2 #include <iostream>
3 using namespace std;
4
5 int main()
6 { // localVar allocated when execution enters the block
7 cout << "Hello" << endl;
8 int localVar; // localVar's scope begins after declaration
9 localVar = 8;
10
11 { // blockVar allocated
12 localVar = 88;
13 int blockVar; // blockVar's scope begins
14 blockVar = 99;
15 cout << blockVar << endl;
16 } // blockVar's scope ends and deallocated
17 // when execution leaves the block
18
19 cout << localVar << endl;
20 } // lcoalVar's scope ends and deallocated

Take that that C++ allocates local variable when the execution enters the block, but the local variable is only
visible (i.e., scope begins) after its declaration statement. The variable's scope ends and is deallocated when the
execution leaves the block. You can verify that local variables are allocated when execution enters the block
using a graphic debugger (on CodeBlock or Eclipse) - Try it out!

Automatic variables are not initialized. You MUST assign an initial value. Compiler may not issue a warning/error
if you use uninitialized local variable.

Automatic variables are typically allocated in a function stack (a Last-in-First-out LIFO queue), where the new
data is stacked on top of the existing data. When a function is called, the caller pushes the arguments onto the
stack. The function's local variables are also pushed (allocated) onto the stack. When the function exits, the top-
of-stack pointer is reset and all variables are freed.

If the inner block has a variable with the same name of the outer block (e.g., rename blockVar to localVar in
the above example), we say that the inner block's variable hides the outer block's variable. The outer block's
variable is temporarily out of scope, until the inner block exits.

Register Automatic Variables ("register" Specifier)


You can use the "register" specifier to suggest to the compiler to put an automatic variable in a register for
faster access. This is often unnecessary, as an optimizing compiler can do this automatically.

2.2  Static Variables ("static" Specifier)


As mentioned, a static variable:
1. is allocated when the execution begins and lasts for the entire duration of the program;
2. retains its memory and contents throughout the program execution. An static variable declared inside a
function retains its value even when the function exits.

Static variables are initialized to zero (all its bits set to 0), if no initial values are provided. All elements of static
array and structures are initialized to zero too. On the other hand, automatic local variables are not initialized.

Static variables are allocated at fixed memory locations (instead of function stack) as they last for the entire
program duration.

Static variables has three types of linkage:


1. external: global static variables visible in other source files - defined outside all functions.
2. internal: global static file-scope variables visible in the file that it is defined - defined outside all functions
with keyword static.
3. no linkage: local static variable visible within a function or block for which it is defined - defined inside a
function with keyword static.

For example,

1 /* Test static variables of various linkage (TestStatic.cpp) */


2 #include <iostream>
3 using namespace std;
4
5 // All static variables are allocated when the program starts and
6 // last for the entire program duration
7 // Uninitialized static variables are initialized to zero (all bits set to zero)
8 int allFileVar; // static variable, external linkage
9 // accessible (scope) by other files with "extern" specifier
10 static int thisFileVar; // static variable, internal linkage
11 // accessible (scope) by all functions in this file
12 void fun();
13
14 int main() {
15 cout << allFileVar << endl; // 0
16 fun();
17 fun();
18 fun();
19 cout << thisFileVar << endl; // 0
20 }
21
22 void fun() {
23 cout << thisFileVar << endl; // 0
24 {
25 static int blockVar; // static variable, no linkage
26 // scope is this block
27 // It retains its value across function calls
28 ++blockVar;
29 cout << "blockVar is " << blockVar << endl; // 1, 2, 3
30 }
31 }

Try using a graphic debugger (CodeBlocks or Eclipse) to check the duration (created/destroyed) and scope
(visible) of the variables.

The static variable blockVar, which is declared inside the function fun(), has local scope and no linkage. It
can only visible (scope) inside the block in which it is defined, just like an automatic variable. But unlike
automatic variable, static variable retains its memory (and value) across multiple function calls. Both the
static variables allFileVar and thisFileVar are visible (scope) immediately after their declarations.
thisFileVar, with "static" specifier, has internal linkage and can be used by all functions in this file. On the
other hand, allFileVar, without the "static" specifier, has external linkage and can be used in other files with
"extern" specifier (which will be described later).

static class members


A static class member (data or function) belongs to the class, instead of instances. It can be referenced
directly from the class, without creating instances, via Classname::staticMemberName. A static data
member retains its value throughout the program execution.

2.3  External Variables ("extern" Specifier)


The extern specifies linkage to another source file. It tells the compiler that the identifier is defined in another
(external) source file.

// File1.cpp
extern int globalVar; // Declare that this variable is defined in another file (external variable).
// Cannot assign an value.
// Need to link to the other file.

// File2.cpp
int globalVar = 88; // Definition here
// or
extern int globalVar = 88; // The "extern" specifier is optional.
// The initialization indicates definition

C/C++ has the so-called "one definition rule", which states that a variable can only be defined once. In the
above example, the statement "int globalVar" in File2.cpp is called the defining declaration (or simply
definition), which causes memory to be allocated; the statement "extern int globalVar" in File1.cpp is
called referencing declaration (or simply declaration), which does not allocate memory but links to an existing
memory.

2.4  Summary
Recap that the duration determines when the variable is created and destroyed; scope determines which part of
the program can access the variable; and linkage determines whether the variable is available in other source
files.

Description Duration Scope Linkage


Variables declared inside a function (or Automatic local Block Block (or None
block) variables Local)
Variables declared inside a function (or Static variables with Static (Entire Block (or None
block) with static specifier no linkage program) Local)
Variables declared outside all functions Static variables with Static (Entire File (or External
external linkage program) Global)
Variables declared outside all functions Static variables with Static (Entire File (or Internal
with static specifier internal linkage program) Global)

2.5  CV-Qualifiers (const and volatile) and mutable


The "const" qualifier indicates that the content of the storage location shall not be changed after initialized.

The "volatile" qualifier indicates that the content of the storage location could be altered outside your program,
e.g., by an external hardware. This qualifier is needed to tell compiler not to optimize this particular location
(e.g., not to store in register, not to re-order the statement, or collapse multiple statements).

The mutable specifier can be used in struct or class to indicate that a particular data member is modifiable
even though the instance is declared const.

"const" Global Variables


By default, a global variable (defined outside all functions) has external linkage. However, const global variable
has internal linkage (as if static specifier is used). As the result, you can place all const global variables in a
header file, and include the header in all the source files. To set a const global variable to external linkage,
include "extern" specifier.

2.6  Function and Linkage


So far, we were discussing about variables. By default, functions have duration of the entire program, and
external linkage (can be shared across file).

You use use the "static" specifier to confine the function to internal linkage (accessible in this file only). The
"one definition only" rule applies to all non-inline functions. That is, there is only one function definition. Each
file shall have the function prototype (declaration). Since inline functions are often placed in the header, which
will be included in all file, the "one definition rule" makes an exception. However, all copies of inline function
shall be identical.
If a function is declared static in its prototype, the C++ compiler/linker search the current file only for the
function definition. Otherwise, C++ compiler/linker searches all the program files. It issues an error if it finds
more than one definitions. If the function is not found in all the program files, it then searches the libraries.

extern "C" vs. extern "C++"


Many C++ compilers use a so-called "name mangling scheme" to support function overloading (i.e., many
versions for the same function name differentiated by their parameter list). You can use keyword extern to
indicate the naming protocol of the function, for example,

extern "C" void function1 (int, int); // Use C function naming protocol
// without name manglind
extern "C++" void function2 (double, double); // Use C++ naming mangling
extern void function (double, double); // Same as above

2.7  Other Scopes
Besides the block-scope (local-scope), file-scope (global-scope) with internal or external linkage, there are:
Function Scope: A label (identified by an identifier followed by a colon, e.g., loop:) can be referenced
within the entire function in which it is defined.
Function Prototype Scope: The optional identifiers defined in the function prototype is confined to the
function prototype only. There are not bind to the function definition.
Class Scope: Class members (data and function) have class scope and are visible inside the class definition.
You can use the same identifier in two different classes. You cannot access a class member directly outside
the class definition, even for public members (which is accessed via the dot operator in the form of
objectName.memberName).
Namespace Scope: Name defined under a namespace are visible within the namespace definition only. You
need to use the scope resolution operator to reference the name outside the namespace definition in the
form of namespace::memberName. With the introduction of namespace in C++, the global scope is
changed to global namespace scope, identified by a nameless namespace or ::memberName.

3.  Summary of static Keyword


A static variable defined inside a block has block-scope, but having duration for the entire program. It
retains its memory and value across multiple invocations.
A static global variable defined outside all functions has file-scope with internal linkage (i.e., visible only
to the file in which it is defined, but not other source files). It has duration for the entire program, and
retains its memory and value throughout the program execution. On the other hand, a global variable
without the static keyword has file-scope with external linkage. It can be referenced by other file via the
extern keyword.
A static class member belongs to the class, instead of the instances. There is one copy shared by all the
instances. It has class scope. To reference it outside the class, use the scope resolution operator
classname::static_membername.

4.  Type Casting Operators


C++ supports C's explicit type casting operations (new-type)value (C-style cast), or new-type(value)
(Function-style cast), called regular cast. Regular cast is too lax, and often produces expected result.
C++ introduces 4 new type casting operators: const_cast<new-type>(value), static_cast<new-type>
(value), dynamic_cast<new-type>(value), reinterpret_cast<new-type>(value) to regulate type
casting. Although the old styles is still acceptable in C++, new styles are preferable.

static_cast
static_cast is used for force implicit conversion. It throws a type-cast error if the conversion fails.

You can use static_cast to convert values of various fundamental types, e.g., from double to int, from
float to long.

[TODO] Example

dynamic_cast
dynamic_cast can be used to verify the type of an object at runtime, before performing the type conversion. It
is primarily used to perform "safe downcasting"

The syntax is:

dynamic_cast<Type *>(ptr)

It converts the pointer ptr to a pointer of the type Type, in runtime, if ptr is pointing to an object of Type, or
its direct or indirect subclass. Otherwise, it returns 0, or null pointer.

You can use dynamic_cast in a condition to ascertain the type of the object, before performing certain
operations.

[TODO] Example

const_cast
The const_cast can be used to drop the const label, so as to alter its contents (i.e., cast away the const-ness
or volatile-ness). This is useful if you have a variable which is constant most of the time, but need to be
changed in some circumstances. You can declare the variable as const, and use const_cast to alter its value.
The syntax is:

const_cast<Type>(expression)

const_cast cannot change the type of an object.

[TODO] Example

reinterpret_cast
Used for low-level casts that yield implementation-dependent result, e.g., casting a pointer to an int.

5.  Summary of const Keyword


A const variable (local or global) cannot be modified, and must be initialized during declaration. By convention,
these const variable are named in uppercase.

const int SIZE = 5;

int main() {
const int ROWS = 8;
......
}

Function's Parameters
In C++, objects are pass-by-value into function by default, which has no side effect but involves calling the copy
constructor to make a clone copy (an expensive operation for huge objects). Objects should be passed into
function by reference as far as possible for performance. However, in pass-by-reference, changes made inside
the function have side effect of modifying the caller's object. We could use keyword const to enforce
immutability, if we do not wish to change the object inside the function. Instead of using pass-by-value to
prevent side-effect, it is better to use pass-by-reference-to-const.

void fun (MyClass obj); // pass-by-value (default)


// Invoke copy constructor to make a clone copy
// No side-effect
void fun (MyClass & obj); // pass-by-reference, have side-effect
void fun (const MyClass & obj) // pass-by-reference-to-const
// No side-effect. Cannot modify caller's copy

You can also use const for array to prevent it from being modified inside the function (as array is an pointer).

It is recommended to leave out the const for fundamental types (int, double), as they are passed by value.
Although you can use const keyword to prevent modification of these local parameters (which is rarely
necessary), the keyword can be confusing. If needed, you may include it in the implementation, but leave them
out from the header.

const function parameters = not modifying the caller's copy (in pass-by-reference).

Function's Return Value


For object return type, we can use const to prevent it to be used as the lvalue, e.g., f() = x. A const return
object cannot be a lvalue (e.g., for assignment); while a non-const return object can.

For example, if we overload the + operator for the MyComplex class:

MyComplex operator+ (const MyComplex & lhs, const MyComplex & rhs);
// non-const return type can be used as lvalue

MyComplex c1, c2, c3;


c1 + c2 = c3; // Valid if the return type is non-const
// Not meaningful and possibly a misspelling of
// c1 + c2 == c3

Function return value of fundamental types can never be the lvalue, and trigger compilation error.

Class
A const data member cannot be modified (as usual).

A const member function (with const keyword at the end of the function) cannot modify data members.

Object
A const object can only invoke const member function. It cannot invoke non-const member function. A non-
const object can invoke both const and non-const member function.

If a function is overloaded with a const and a non-const version, a const object will match with a const
member function. A non-const object will match with a non-const function. For example, the at() function of
string class has two versions:

char & at (size_t pos); // non-const member function


const char & at (size_t pos) const; // const member function

A const string object will invoke the const version, which returns a const char & that cannot be used a
lvalue.
const string str1("hello"); // const string object
cout << str1.at(1); // okay
str1.at(1) = 'x'; // error - returned const char & cannot be lvalue

string str2("again"); // non-const string object


str2.at(1) = 'x'; // okay

Pointer
1. Non-constant pointer to constant data: Data pointed to CANNOT be changed; but pointer CAN be
changed to point to another data. For example,

int i1 = 8, i2 = 9;
const int * iptr = &i1; // non-constant pointer pointing to constant data
// *iptr = 9; // error: assignment of read-only location
iptr = &i2; // okay

2. Constant pointer to non-constant data: Data pointed to CAN be changed; but pointer CANNOT be
changed to point to another data. For example,

int i1 = 8, i2 = 9;
int * const iptr = &i1; // constant pointer pointing to non-constant data
*iptr = 9; // okay
// iptr = &i2; // error: assignment of read-only variable

3. Constant pointer to constant data: Data pointed to CANNOT be changed; and pointer CANNOT be
changed to point to another data. For example,

int i1 = 8, i2 = 9;
const int * const iptr = &i1; // constant pointer pointing to constant data
// *iptr = 9; // error: assignment of read-only variable
// iptr = &i2; // error: assignment of read-only variable

4. Non-constant pointer to non-constant data: Data pointed to CAN be changed; and pointer CAN be
changed to point to another data. For example,

int i1 = 8, i2 = 9;
int * iptr = &i1; // non-constant pointer pointing to non-constant data
*iptr = 9; // okay
iptr = &i2; // okay

If the keyword const appears before (to the left) of the *, what is pointed-to is a constant. If it appears after (to
the right) of *, the pointer itself is a constant.

6.  C++ Keywords

Keywords Ported from C Language (32)


Types: int, short, long, char, float, double, void, signed, unsigned, typedef.
Flow Control: if, else, switch, case, default, while, do, for, break, continue, goto, return.

Storage Qualifiers: const, volatile, auto, extern, register, static.

Operators: sizeof.
Compound Types: enum, struct, union.

C++98/03 Keywords (42)


Class: class, public, private, protected, friend, explicit (constructor), inline (function), virtual
(polymorphism), operator (overloading).
Template: template, export, typename.

Namespace: this,namespace, using.


Types: bool, true, false, wchar_t.

Memory Allocation: new, delete,


Exception Handling: try, catch, throw.
Operators: and (&&), or (||), not (!), xor (^), compl (~), bitand (&), bitor (|), and_eq (&=), or_eq (|=),
not_eq (!=), xor_eq (^=).
Type and Casting Operators: typeid, static_cast, const_cast, dynamic_cast, reinterpret_cast.
Storage Qualifier: mutable.
Others: asm (inline assembly block).

C++11 Keywords (10)


Types: char16_t, char_32_t, nullptr.
Storage Qualifiers: thread_local.
Others: alignas, alignof, constexpr, decltype, noexcept, static_asert.

Link to "C++ Language References & Resources"

Latest version tested: GCC g++ 4.6.2


Last modified: May, 2013

Feedback, comments, corrections, and errata can be sent to Chua Hock-Chuan (ehchua@ntu.edu.sg)   |  
HOME

You might also like