C++ Language - C++ Tutorials
C++ Language - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
Introduction:
Compilers Basics of C++
Basics of C++:
Structure of a
Structure of a program
Variables and types
program
Constants
Variables and types Operators
Consants Basic Input/Output
Operators
Basic Input/Output
Program structure
Program sructure:
Statements and fow Control Structures
control Functions
Functions Overloads and templates
Overloads and Name visibility
templates
Name
Compound data types
visibility
Compound data types: Arrays
Arrays Character sequences
Character sequences Pointers
Pointers
Dynamic Memory
Data structures
Dynamic memory
Other data types
Data
sructures
Other data Classes
types
Classes (I)
Classes:
Classes (II)
Classes (I) Special members
Classes (II) Friendship and inheritance
Special members Polymorphism
Friendship and inheritance
Polymorphism
Other language features
Other language features:
Type conversions Type conversions
Exceptions Exceptions
Preprocessor directives Preprocessor directives
Standard library:
Input/output with
C++ Standard Library
fles
Input/Output with fles
http://www.cplusplus.com/doc/tutorial/[03/12/2018 00:48:29]
Compilers - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
Tutorials Compilers
C++ Language The essential tools needed to follow these tutorials are a computer and a compiler toolchain able to compile C++ code
Ascii and build the programs to run on it.
Codes
Boolean Operations C++ is a language that has evolved much over the years, and these tutorials explain many features added recently to
Numerical Bases the language. Therefore, in order to properly follow the tutorials, a recent compiler is needed. It shall support (even if
only partially) the features introduced by the 2011 standard.
C++ Language
Many compiler vendors support the new features at diferent degrees. See the bottom of this page for some compilers
Introduction:
that are known to support the features needed. Some of them are free!
Compilers
Basics of C++: If for some reason, you need to use some older compiler, you can access an older version of these tutorials here (no
Structure of a longer updated).
program
Variables and types
Consants What is a compiler?
Operators Computers understand only one language and that language consists of sets of instructions made of ones and zeros.
Basic Input/Output This computer language is appropriately called machine language.
Program sructure:
Statements and fow A single instruction to a computer could look like this:
control
00000 10011110
Functions
Overloads and
A particular computer's machine language program that allows a user to input two numbers, adds the two numbers
templates together, and displays the total could include these machine code instructions:
Name
visibility 00000 10011110
Compound data types: 00001 11110100
Arrays 00010 10011110
Character sequences
00011 11010100
Pointers
00100 10111111
Dynamic memory
00101 00000000
Data
sructures
As you can imagine, programming a computer directly in machine language using only ones and zeros is very tedious
Other data and error prone. To make programming easier, high level languages have been developed. High level programs also
types make it easier for programmers to inspect and understand each other's programs easier.
Classes:
Classes (I) This is a portion of code written in C++ that accomplishes the exact same purpose:
Classes (II)
Special members
1 int a, b, sum;
2
Friendship and inheritance 3 cin >> a;
4 cin >> b;
Polymorphism 5
Other language features: 6 sum = a + b;
7 cout << sum <<
Type conversions endl;
Exceptions
Preprocessor directives
Standard library: Even if you cannot really understand the code above, you should be able to appreciate how much easier it will be to
Input/output with program in the C++ language as opposed to machine language.
fles
Because a computer can only understand machine language and humans wish to write in high level languages high level
Compilers languages have to be re-written (translated) into machine language at some point. This is done by special programs
called compilers, interpreters, or assemblers that are built into the various programming applications.
Code::Blocks
Dev-C++ C++ is designed to be a compiled language, meaning that it is generally translated into machine language that can be
Visual Studio understood directly by the system, making the generated program highly efcient. For that, a set of tools are needed,
Express known as the development toolchain, whose core are a compiler and its linker.
Console programs
Console programs are programs that use text to communicate with the user and the environment, such as printing text
to the screen or reading input from a keyboard.
Console programs are easy to interact with, and generally have a predictable behavior that is identical across all
platforms. They are also simple to implement and thus are very useful to learn the basics of a programming language:
The examples in these tutorials are all console programs.
The way to compile console programs depends on the particular tool you are using.
The easiest way for beginners to compile C++ programs is by using an Integrated Development Environment (IDE). An
IDE generally integrates several development tools, including a text editor and tools to compile programs directly from
it.
Here you have instructions on how to compile and run console programs using diferent free Integrated Development
Interfaces (IDEs):
If you happen to have a Linux or Mac environment with development features, you should be able to compile any of the
examples directly from a terminal just by including C++11 fags in the command for the compiler:
http://www.cplusplus.com/doc/tutorial/introduction/[03/12/2018 00:48:55]
Compilers - C++ Tutorials
Next:
Structure of a program
Index
http://www.cplusplus.com/doc/tutorial/introduction/[03/12/2018 00:48:55]
Structure of a program - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
http://www.cplusplus.com/doc/tutorial/program_structure/[03/12/2018 00:49:16]
Structure of a program - C++ Tutorials
Classes (I)
Classes (II) The function named main is a special function in all C++ programs; it is the function called when the program is
Special members run. The execution of all C++ programs begins with the main function, regardless of where the function is
Friendship and inheritance
actually located within the code.
Polymorphism
Lines 5 and 7: { and }
Other language features: The open brace ({) at line 5 indicates the beginning of main's function defnition, and the closing brace (}) at line
Type conversions 7, indicates its end. Everything between these braces is the function's body that defnes what happens when
Exceptions main is called. All functions use braces to indicate the beginning and end of their defnitions.
Preprocessor directives
Standard library: Line 6: sd::cout << "Hello World!";
Input/output with
This line is a C++ statement. A statement is an expression that can actually produce some efect. It is the meat
of a program, specifying its actual behavior. Statements are executed in the same order that they appear within
fles
a function's body.
This statement has three parts: First, sd::cout, which identifes the standard character output device (usually,
this is the computer screen). Second, the insertion operator (<<), which indicates that what follows is inserted
into sd::cout. Finally, a sentence within quotes ("Hello world!"), is the content inserted into the standard
output.
Notice that the statement ends with a semicolon (;). This character marks the end of the statement, just as the
period ends a sentence in English. All C++ statements must end with a semicolon character. One of the most
common syntax errors in C++ is forgetting to end a statement with a semicolon.
You may have noticed that not all the lines of this program perform actions when the code is executed. There is a line
containing a comment (beginning with //). There is a line with a directive for the preprocessor (beginning with#).
There is a line that defnes a function (in this case, the main function). And, fnally, a line with a statements ending with
a semicolon (the insertion into cout), which was within the block delimited by the braces ( { } ) of the main function.
The program has been structured in diferent lines and properly indented, in order to make it easier to understand for
the humans reading it. But C++ does not have strict rules on indentation or on how to split instructions in diferent
lines. For example, instead of
1 int main ()
2{
3 sd::cout << " Hello
4 World!";
}
all in a single line, and this would have had exactly the same meaning as the preceding code.
In C++, the separation between statements is specifed with an ending semicolon (;), with the separation into
diferent lines not mattering at all for this purpose. Many statements can be written in a single line, or each statement
can be in its own line. The division of code in diferent lines serves only to make it more legible and schematic for the
humans that may read it, but has no efect on the actual behavior of the program.
http://www.cplusplus.com/doc/tutorial/program_structure/[03/12/2018 00:49:16]
Structure of a program - C++ Tutorials
3
4 int main ()
5{
6 sd::cout << "Hello World! ";
7 sd::cout << "I'm a C++ program";
8 }
In this case, the program performed two insertions into sd::cout in two diferent statements. Once again, the
separation in diferent lines of code simply gives greater readability to the program, since main could have been
perfectly valid defned in this way:
int main () { sd::cout << " Hello World! "; sd::cout << " I'm a C++ program ";
}
The source code could have also been divided into more code lines instead:
1 int main ()
2{
3 sd::cout <<
4 "Hello World!";
5 sd::cout
6 << "I'm a C++ program";
7 }
And the result would again have been exactly the same as in the previous examples.
Preprocessor directives (those that begin by #) are out of this general rule since they are not statements. They are lines
read and processed by the preprocessor before proper compilation begins. Preprocessor directives must be specifed in
their own line and, because they are not statements, do not have to end with a semicolon (;).
Comments
As noted above, comments do not afect the operation of the program; however, they provide an important tool to
document directly within the source code what the program does and how it operates.
1 // line comment
2 /* block comment */
The frst of them, known as line comment, discards everything from where the pair of slash signs (//) are found up to
the end of that same line. The second one, known as block comment, discards everything between the /* characters
and the frst appearance of the */ characters, with the possibility of including multiple lines.
http://www.cplusplus.com/doc/tutorial/program_structure/[03/12/2018 00:49:16]
Structure of a program - C++ Tutorials
If comments are included within the source code of a program without using the comment characters combinations //,
/* or */, the compiler takes them as if they were C++ expressions, most likely causing the compilation to fail with one,
or several, error messages.
cout is part of the standard library, and all the elements in the standard C++ library are declared within what is called
a namespace: the namespace sd.
In order to refer to the elements in the sd namespace a program shall either qualify each and every use of elements of
the library (as we have done by prefxing cout with sd::), or introduce visibility of its components. The most typical
way to introduce visibility of these components is by means of using declarations:
The above declaration allows all elements in the sd namespace to be accessed in an unqualifed manner (without the
sd:: prefx).
With this in mind, the last example can be rewritten to make unqualifed uses of cout as:
1 // my second program in C++ Hello World! I'm a C++ program
2 #include <iosream>
3 using namespace sd;
4
5 int main ()
6{
7 cout << "Hello World! ";
8 cout << "I'm a C++ program";
9}
Both ways of accessing the elements of the sd namespace (explicit qualifcation and using declarations) are valid in
C++ and produce the exact same behavior. For simplicity, and to improve readability, the examples in these tutorials
will more often use this latter approach with using declarations, although note that explicit qualifcation is the only way
to guarantee that name collisions never happen.
Previous: Next:
Compilers Variables and types
Index
http://www.cplusplus.com/doc/tutorial/program_structure/[03/12/2018 00:49:16]
Structure of a program - C++ Tutorials
http://www.cplusplus.com/doc/tutorial/program_structure/[03/12/2018 00:49:16]
Variables and types - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
http://www.cplusplus.com/doc/tutorial/variables/[03/12/2018 00:49:41]
Variables and types - C++ Tutorials
Classes (I)
Classes (II)
C++ uses a number of keywords to identify operations and data descriptions; therefore, identifers created by a
Special members programmer cannot match these keywords. The standard reserved keywords that cannot be used for programmer
Friendship and inheritance created identifers are:
Polymorphism
Other language features: alignas, alignof, and, and_eq, asm, auto, bitand, bitor, bool, break, case, catch, char, char16_t,
Type conversions char32_t, class, compl, cons, consexpr, cons_cas, continue, decltype, default, delete, do, double,
Exceptions dynamic_cas, else, enum, explicit, export, extern, false, foat, for, friend, goto, if, inline, int,
long, mutable, namespace, new, noexcept, not, not_eq, nullptr, operator, or, or_eq, private,
Preprocessor directives
protected, public, regiser, reinterpret_cas, return, short, signed, sizeof, satic, satic_assert,
Standard library: satic_cas, sruct, switch, template, this, thread_local, throw, true, try, typedef, typeid, typename,
Input/output with union, unsigned, using, virtual, void, volatile, wchar_t, while, xor, xor_eq
fles
Specifc compilers may also have additional specifc reserved keywords.
Very important: The C++ language is a "case sensitive" language. That means that an identifer written in capital
letters is not equivalent to another one with the same name but written in small letters. Thus, for example, the RESULT
variable is not the same as the result variable or the Result variable. These are three diferent identifers identifying
three diferent variables.
Fundamental data types are basic types implemented directly by the language that represent the basic storage units
supported natively by most systems. They can mainly be classifed into:
Character types: They can represent a single character, such as 'A' or '$'. The most basic type is char, which
is a one-byte character. Other types are also provided for wider characters.
Numerical integer types: They can store a whole number value, such as 7 or 1024. They exist in a variety of
sizes, and can either be signed or unsigned, depending on whether they support negative values or not.
Floating-point types: They can represent real values, such as 3.14 or 0.01, with diferent levels of precision,
depending on which of the three foating-point types is used.
Boolean type: The boolean type, known in C++ as bool, can only represent one of two states, true or false.
http://www.cplusplus.com/doc/tutorial/variables/[03/12/2018 00:49:41]
Variables and types - C++ Tutorials
* The names of certain integer types can be abbreviated without their signed and int components - only the part not
in italics is required to identify the type, the part in italics is optional. I.e., signed short int can be abbreviated as
signed short, short int, or simply short; they all identify the same fundamental type.
Within each of the groups above, the diference between types is only their size (i.e., how much they occupy in
memory): the frst type in each group is the smallest, and the last is the largest, with each type being at least as large
as the one preceding it in the same group. Other than that, the types in a group have the same properties.
Note in the panel above that other than char (which has a size of exactly one byte), none of the fundamental types has
a standard size specifed (but a minimum size, at most). Therefore, the type is not required (and in many cases is not)
exactly this minimum size. This does not mean that these types are of an undetermined size, but that there is no
standard size across all compilers and machines; each compiler implementation may specify the sizes for these types
that ft the best the architecture where the program is going to run. This rather generic size specifcation for types gives
the C++ language a lot of fexibility to be adapted to work optimally in all kinds of platforms, both present and future.
Type sizes above are expressed in bits; the more bits a type has, the more distinct values it can represent, but at the
same time, also consumes more space in memory:
For integer types, having more representable values means that the range of values they can represent is greater; for
example, a 16-bit unsigned integer would be able to represent 65536 distinct values in the range 0 to 65535, while its
signed counterpart would be able to represent, on most cases, values between -32768 and 32767. Note that the range
of positive values is approximately halved in signed types compared to unsigned types, due to the fact that one of the
16 bits is used for the sign; this is a relatively modest diference in range, and seldom justifes the use of unsigned
types based purely on the range of positive values they can represent.
For foating-point types, the size afects their precision, by having more or less bits for their signifcant and exponent.
If the size or precision of the type is not a concern, then char, int, and double are typically selected to represent
characters, integers, and foating-point values, respectively. The other types in their respective groups are only used in
very particular cases.
The properties of fundamental types in a particular system and compiler implementation can be obtained by using the
numeric_limits classes (see standard header <limits>). If for some reason, types of specifc sizes are needed, the
library defnes certain fxed-size type aliases in header <csdint>.
http://www.cplusplus.com/doc/tutorial/variables/[03/12/2018 00:49:41]
Variables and types - C++ Tutorials
The types described above (characters, integers, foating-point, and boolean) are collectively known as arithmetic
types. But two additional fundamental types exist: void, which identifes the lack of type; and the type nullptr, which
is a special type of pointer. Both types will be discussed further in a coming chapter about pointers.
C++ supports a wide variety of types based on the fundamental types discussed above; these other types are known
as compound data types, and are one of the main strengths of the C++ language. We will also see them in more detail
in future chapters.
Declaration of variables
C++ is a strongly-typed language, and requires every variable to be declared with its type before its frst use. This
informs the compiler the size to reserve in memory for the variable and how to interpret its value. The syntax to declare
a new variable in C++ is straightforward: we simply write the type followed by the variable name (i.e., its identifer).
For example:
1 int a;
2 foat mynumber;
These are two valid declarations of variables. The frst one declares a variable of type int with the identifer a. The
second one declares a variable of type foat with the identifer mynumber. Once declared, the variables a and mynumber
can be used within the rest of their scope in the program.
If declaring more than one variable of the same type, they can all be declared in a single statement by separating their
identifers with commas. For example:
int a, b,
c;
This declares three variables (a, b and c), all of them of type int, and has exactly the same meaning as:
1 int a;
2 int b;
3 int c;
To see what variable declarations look like in action within a program, let's have a look at the entire C++ code of the
example about your mental memory proposed at the beginning of this chapter:
http://www.cplusplus.com/doc/tutorial/variables/[03/12/2018 00:49:41]
Variables and types - C++ Tutorials
return 0;
23 }
Don't be worried if something else than the variable declarations themselves look a bit strange to you. Most of it will be
explained in more detail in coming chapters.
Initialization of variables
When the variables in the example above are declared, they have an undetermined value until they are assigned a
value for the frst time. But it is possible for a variable to have a specifc value from the moment it is declared. This is
called the initialization of the variable.
In C++, there are three ways to initialize variables. They are all equivalent and are reminiscent of the evolution of the
language over the years:
The frst one, known as c-like initialization (because it is inherited from the C language), consists of appending an
equal sign followed by the value to which the variable is initialized:
int x =
0;
A second method, known as constructor initialization (introduced by the C++ language), encloses the initial value
between parentheses (()):
int x (0);
Finally, a third method, known as uniform initialization, similar to the above, but using curly braces ({}) instead of
parentheses (this was introduced by the revision of the C++ standard, in 2011):
int x {0};
All three ways of initializing variables are valid and equivalent in C++.
1 // initialization of variables 6
2
3 #include <iosream>
4 using namespace sd;
5
6 int main ()
7 {
8 int a=5; // initial value: 5
9 int b(3); // initial value: 3
10 int c{2}; // initial value: 2
11 int result; // initial value
http://www.cplusplus.com/doc/tutorial/variables/[03/12/2018 00:49:41]
Variables and types - C++ Tutorials
12 undetermined
13
14 a = a + b;
15 result = a - c;
16 cout << result;
17
18 return 0;
}
1 int foo = 0;
2 auto bar = foo; // the same as: int bar = foo;
Here, bar is declared as having an auto type; therefore, the type of bar is the type of the value used to initialize it: in
this case it uses the type of foo, which is int.
Variables that are not initialized can also make use of type deduction with the decltype specifer:
1 int foo = 0;
2 decltype(foo) bar; // the same as: int bar;
auto and decltype are powerful features recently added to the language. But the type deduction features they
introduce are meant to be used either when the type cannot be obtained by other means or when using it improves
code readability. The two examples above were likely neither of these use cases. In fact they probably decreased
readability, since, when reading the code, one has to search for the type of foo to actually know the type of bar.
Introduction to strings
Fundamental types represent the most basic types handled by the machines where the code may run. But one of the
major strengths of the C++ language is its rich set of compound types, of which the fundamental types are mere
building blocks.
An example of compound type is the sring class. Variables of this type are able to store sequences of characters, such
as words or sentences. A very useful feature!
A frst diference with fundamental data types is that in order to declare and use objects (variables) of this type, the
program needs to include the header where the type is defned within the standard library (header <sring>):
http://www.cplusplus.com/doc/tutorial/variables/[03/12/2018 00:49:41]
Variables and types - C++ Tutorials
As you can see in the previous example, strings can be initialized with any valid string literal, just like numerical type
variables can be initialized to any valid numerical literal. As with fundamental types, all initialization formats are valid
with strings:
Strings can also perform all the other basic operations that fundamental data types can, like being declared without an
initial value and change its value during execution:
Note: inserting the endl manipulator ends the line (printing a newline character and fushing the stream).
The sring class is a compound type. As you can see in the example above, compound types are used in the same way
as fundamental types: the same syntax is used to declare variables and to initialize them.
For more details on standard C++ strings, see the sring class reference.
Previous: Next:
Structure of a program Constants
Index
http://www.cplusplus.com/doc/tutorial/variables/[03/12/2018 00:49:41]
Constants - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
Tutorials Constants
C++ Language Constants are expressions with a fxed value.
Ascii
Codes
Boolean Operations Literals
Numerical Bases Literals are the most obvious kind of constants. They are used to express particular values within the source code of a
program. We have already used some in previous chapters to give specifc values to variables or to express messages
C++ Language
we wanted our programs to print out, for example, when we wrote:
Introduction:
Compilers a =
5;
Basics of C++:
Structure of a
program
The 5 in this piece of code was a literal constant.
Variables and types
Consants Literal constants can be classifed into: integer, foating-point, characters, strings, Boolean, pointers, and user-defned
Operators literals.
Basic Input/Output
Program sructure: Integer Numerals
Statements and fow
control 1 1776
2 707
Functions 3 -273
Overloads and
templates
Name These are numerical constants that identify integer values. Notice that they are not enclosed in quotes or any other
visibility special character; they are a simple succession of digits representing a whole number in decimal base; for example,
Compound data types: 1776 always represents the value one thousand seven hundred seventy-six.
Arrays
In addition to decimal numbers (those that most of us use every day), C++ allows the use of octal numbers (base 8)
Character sequences
and hexadecimal numbers (base 16) as literal constants. For octal literals, the digits are preceded with a 0 (zero)
Pointers character. And for hexadecimal, they are preceded by the characters 0x (zero, x). For example, the following literal
Dynamic memory constants are all equivalent to each other:
Data
sructures 1 75 // decimal
2 0113 // octal
Other data 3 0x4b // hexadecimal
types
Classes:
http://www.cplusplus.com/doc/tutorial/constants/[03/12/2018 00:50:03]
Constants - C++ Tutorials
Classes (I) All of these represent the same number: 75 (seventy-fve) expressed as a base-10 numeral, octal numeral and
Classes (II) hexadecimal numeral, respectively.
Special members
These literal constants have a type, just like variables. By default, integer literals are of type int. However, certain
Friendship and inheritance
sufxes may be appended to an integer literal to specify a diferent integer type:
Polymorphism
Other language features:
Sufx Type modifer
Type conversions
u or U unsigned
Exceptions
l or L long
Preprocessor directives
ll or LL long long
Standard library:
Input/output with
Unsigned may be combined with any of the other two in any order to form unsigned long or unsigned long long.
fles
For example:
1 75 // int
2 75u // unsigned int
3 75l // long
4 75ul // unsigned long
5 75lu // unsigned long
In all the cases above, the sufx can be specifed using either upper or lowercase letters.
1 3.14159 // 3.14159
2 6.02e23 // 6.02 x 10^23
3 1.6e-19 // 1.6 x 10^-19
4 3.0 // 3.0
These are four valid numbers with decimals expressed in C++. The frst number is PI, the second one is the number of
Avogadro, the third is the electric charge of an electron (an extremely small number) -all of them approximated-, and
the last one is the number three expressed as a foating-point numeric literal.
The default type for foating-point literals is double. Floating-point literals of type foat or long double can be specifed
by adding one of the following sufxes:
Sufx Type
f or F foat
l or L long double
For example:
Any of the letters that can be part of a foating-point numerical constant (e, f, l) can be written using either lower or
uppercase letters with no diference in meaning.
http://www.cplusplus.com/doc/tutorial/constants/[03/12/2018 00:50:03]
Constants - C++ Tutorials
1 'z'
2 'p'
3 "Hello world"
4 "How do you do?
"
The frst two expressions represent single-character literals, and the following two represent string literals composed of
several characters. Notice that to represent a single character, we enclose it between single quotes ( '), and to express
a string (which generally consists of more than one character), we enclose the characters between double quotes (").
Both single-character and string literals require quotation marks surrounding them to distinguish them from possible
variable identifers or reserved keywords. Notice the diference between these two expressions:
x
'x'
Here, x alone would refer to an identifer, such as the name of a variable or a compound type, whereas 'x' (enclosed
within single quotation marks) would refer to the character literal 'x' (the character that represents a lowercase x
letter).
Character and string literals can also represent special characters that are difcult or impossible to express otherwise in
the source code of a program, like newline (\n) or tab (\t). These special characters are all of them preceded by a
backslash character (\).
For example:
'\n'
'\t'
"Left \t Right"
"one\ntwo\nthree"
Internally, computers represent characters as numerical codes: most typically, they use one extension of the ASCII
character encoding system (see ASCII code for more info). Characters can also be represented in literals using its
numerical code by writing a backslash character (\) followed by the code expressed as an octal (base-8) or
http://www.cplusplus.com/doc/tutorial/constants/[03/12/2018 00:50:03]
Constants - C++ Tutorials
hexadecimal (base-16) number. For an octal value, the backslash is followed directly by the digits; while for
hexadecimal, an x character is inserted between the backslash and the hexadecimal digits themselves (for example:
\x20 or \x4A).
Several string literals can be concatenated to form a single string literal simply by separating them by one or more
blank spaces, including tabs, newlines, and other valid blank characters. For example:
Note how spaces within the quotes are part of the literal, while those outside them are not.
Some programmers also use a trick to include long string literals in multiple lines: In C++, a backslash (\) at the end
of line is considered a line-continuation character that merges both that line and the next into a single line. Therefore
the following code:
1 x = "sring expressed in \
2 two lines"
is equivalent to:
All the character literals and string literals described above are made of characters of type char. A diferent character
type can be specifed by using one of the following prefxes:
Note that, unlike type sufxes for integer literals, these prefxes are case sensitive: lowercase for char16_t and
uppercase for char32_t and wchar_t.
For string literals, apart from the above u, U, and L, two additional prefxes exist:
Prefx Description
The string literal is encoded in the executable using UTF-
u8
8
R The string literal is a raw string
In raw strings, backslashes and single and double quotes are all valid characters; the content of the literal is delimited
by an initial R"sequence( and a fnal )sequence", where sequence is any sequence of characters (including an empty
sequence). The content of the string is what lies inside the parenthesis, ignoring the delimiting sequence itself. For
http://www.cplusplus.com/doc/tutorial/constants/[03/12/2018 00:50:03]
Constants - C++ Tutorials
example:
Both strings above are equivalent to "sring with \\backslash". The R prefx can be combined with any other
prefxes, such as u, L or u8.
Other literals
Three keyword literals exist in C++: true, false and nullptr:
true and false are the two possible values for variables of type bool.
nullptr is the null pointer value.
We can then use these names instead of the literals they were defned to:
After this directive, any occurrence of identifer in the code is interpreted as replacement, where replacement is any
sequence of characters (until the end of the line). This replacement is performed by the preprocessor, and happens
before the program is compiled, thus causing a sort of blind replacement: the validity of the types or syntax involved is
not checked in any way.
http://www.cplusplus.com/doc/tutorial/constants/[03/12/2018 00:50:03]
Constants - C++ Tutorials
For example:
1 #include <iosream> 31.4159
2 using namespace sd;
3
4 #defne PI 3.14159
5 #defne NEWLINE '\n'
6
7 int main ()
8{
9 double r=5.0; // radius
10 double circle;
11
12 circle = 2 * PI * r;
13 cout << circle;
14 cout << NEWLINE;
15
16 }
Note that the #defne lines are preprocessor directives, and as such are single-line instructions that -unlike C++
statements- do not require semicolons (;) at the end; the directive extends automatically until the end of the line. If a
semicolon is included in the line, it is part of the replacement sequence and is also included in all replaced occurrences.
Previous: Next:
Variables and types Operators
Index
Go
C++
Information
Tutorials
Reference
Articles
Forum
Tutorials Operators
C++ Language Once introduced to variables and constants, we can begin to operate with them by using operators. What follows is a
Ascii complete list of operators. At this point, it is likely not necessary to know all of them, but they are all listed here to also
Codes serve as reference.
Boolean Operations
Numerical Bases
Assignment operator (=)
C++ Language
The assignment operator assigns a value to a variable.
Introduction:
Compilers x =
5;
Basics of C++:
Structure of a
program
This statement assigns the integer value 5 to the variable x. The assignment operation always takes place from right to
Variables and types left, and never the other way around:
Consants
Operators x =
Basic Input/Output y;
Program sructure:
Statements and fow
This statement assigns to variable x the value contained in variable y. The value of x at the moment this statement is
control
executed is lost and replaced by the value of y.
Functions
Overloads and Consider also that we are only assigning the value of y to x at the moment of the assignment operation. Therefore, if y
templates changes at a later moment, it will not afect the new value taken by x.
Name
visibility For example, let's have a look at the following code - I have included the evolution of the content stored in the
Compound data types: variables as comments:
Arrays
1 // assignment operator a:4 b:7
Character sequences 2 #include <iosream>
Pointers 3 using namespace sd;
4
Dynamic memory 5 int main ()
6 {
Data 7 int a, b; // a:?, b:?
sructures 8 a = 10; // a:10, b:?
9 b = 4; // a:10, b:4
Other data 10 a = b; // a:4, b:4
types 11 b = 7; // a:4, b:7
12
Classes: 13 cout << "a:";
14 cout << a;
http://www.cplusplus.com/doc/tutorial/operators/[03/12/2018 00:50:24]
Operators - C++ Tutorials
In this expression, y is assigned the result of adding 2 and the value of another assignment expression (which has itself
a value of 5). It is roughly equivalent to:
1 x = 5;
2 y = 2 + x;
x = y = z =
5;
Arithmetic operators ( +, -, *, /, % )
The fve arithmetical operations supported by C++ are:
operator description
+ addition
- subtraction
* multiplication
/ division
% modulo
Operations of addition, subtraction, multiplication and division correspond literally to their respective mathematical
operators. The last one, modulo operator, represented by a percentage sign (%), gives the remainder of a division of
two values. For example:
x = 11 %
3;
results in variable x containing the value 2, since dividing 11 by 3 results in 3, with a remainder of 2.
http://www.cplusplus.com/doc/tutorial/operators/[03/12/2018 00:50:24]
Operators - C++ Tutorials
Compound assignment (+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=)
Compound assignment operators modify the current value of a variable by performing an operation on it. They are
equivalent to assigning the result of an operation to the frst operand:
and the same for all other compound assignment operators. For example:
1 ++x;
2 x+=1;
3 x=x+1;
are all equivalent in its functionality; the three of them increase by one the value of x.
In the early C compilers, the three previous expressions may have produced diferent executable code depending on
which one was used. Nowadays, this type of code optimization is generally performed automatically by the compiler,
thus the three expressions should produce exactly the same executable code.
A peculiarity of this operator is that it can be used both as a prefx and as a sufx. That means that it can be written
either before the variable name (++x) or after it (x++). Although in simple expressions like x++ or ++x, both have
exactly the same meaning; in other expressions in which the result of the increment or decrement operation is
evaluated, they may have an important diference in their meaning: In the case that the increase operator is used as a
prefx (++x) of the value, the expression evaluates to the fnal value of x, once it is already increased. On the other
hand, in case that it is used as a sufx (x++), the value is also increased, but the expression evaluates to the value that
x had before being increased. Notice the diference:
Example 1 Example 2
x = 3; x = 3;
y = ++x; y = x++;
// x contains 4, y contains // x contains 4, y contains
4 3
http://www.cplusplus.com/doc/tutorial/operators/[03/12/2018 00:50:24]
Operators - C++ Tutorials
In Example 1, the value assigned to y is the value of x after being increased. While in Example 2, it is the value x had
before being increased.
Relational and comparison operators ( ==, !=, >, <, >=, <= )
Two expressions can be compared using relational and equality operators. For example, to know if two values are equal
or if one is greater than the other.
The result of such an operation is either true or false (i.e., a Boolean value).
operator description
== Equal to
!= Not equal to
< Less than
> Greater than
<= Less than or equal to
Greater than or equal
>=
to
1 (7 == 5) // evaluates to false
2 (5 > 4) // evaluates to true
3 (3 != 2) // evaluates to true
4 (6 >= 6) // evaluates to true
5 (5 < 5) // evaluates to false
Of course, it's not just numeric constants that can be compared, but just any value, including, of course, variables.
Suppose that a=2, b=3 and c=6, then:
Be careful! The assignment operator (operator =, with one equal sign) is not the same as the equality comparison
operator (operator ==, with two equal signs); the frst one (=) assigns the value on the right-hand to the variable on its
left, while the other (==) compares whether the values on both sides of the operator are equal. Therefore, in the last
expression ((b=2) == a), we frst assigned the value 2 to b and then we compared it to a (that also stores the value
2), yielding true.
http://www.cplusplus.com/doc/tutorial/operators/[03/12/2018 00:50:24]
Operators - C++ Tutorials
The logical operators && and || are used when evaluating two expressions to obtain a single relational result. The
operator && corresponds to the Boolean logical operation AND, which yields true if both its operands are true, and
false otherwise. The following panel shows the result of operator && evaluating the expression a&&b:
The operator || corresponds to the Boolean logical operation OR, which yields true if either of its operands is true,
thus being false only when both operands are false. Here are the possible results of a||b:
|| OPERATOR (or)
a b a || b
true true true
true false true
false true true
false false false
For example:
1 ( (5 == 5) && (3 > 6) ) // evaluates to false ( true && false
2)
( (5 == 5) || (3 > 6) ) // evaluates to true ( true || false )
When using the logical operators, C++ only evaluates what is necessary from left to right to come up with the
combined relational result, ignoring the rest. Therefore, in the last example ((5==5)||(3>6)), C++ evaluates frst
whether 5==5 is true, and if so, it never checks whether 3>6 is true or not. This is known as short-circuit evaluation,
and works like this for these operators:
operator short-circuit
if the left-hand side expression is false, the combined result is false (the right-hand side expression is
&&
never evaluated).
if the left-hand side expression is true, the combined result is true (the right-hand side expression is never
||
evaluated).
This is mostly important when the right-hand expression has side efects, such as altering values:
Here, the combined conditional expression would increase i by one, but only if the condition on the left of && is true,
because otherwise, the condition on the right-hand side (++i<n) is never evaluated.
http://www.cplusplus.com/doc/tutorial/operators/[03/12/2018 00:50:24]
Operators - C++ Tutorials
If condition is true, the entire expression evaluates to result1, and otherwise to result2.
For example:
1 // conditional operator 7
2 #include <iosream>
3 using namespace sd;
4
5 int main ()
6 {
7 int a,b,c;
8
9 a=2;
10 b=7;
11 c = (a>b) ? a : b;
12
13 cout << c << '\n';
14 }
In this example, a was 2, and b was 7, so the expression being evaluated (a>b) was not true, thus the frst value
specifed after the question mark was discarded in favor of the second value (the one after the colon) which was b (with
a value of 7).
Comma operator ( , )
The comma operator (,) is used to separate two or more expressions that are included where only one expression is
expected. When the set of expressions has to be evaluated for a value, only the right-most expression is considered.
would frst assign the value 3 to b, and then assign b+2 to variable a. So, at the end, variable a would contain the value
5 while variable b would contain value 3.
http://www.cplusplus.com/doc/tutorial/operators/[03/12/2018 00:50:24]
Operators - C++ Tutorials
1 int i;
2 foat f = 3.14;
3 i = (int) f;
The previous code converts the foating-point number 3.14 to an integer value (3); the remainder is lost. Here, the
typecasting operator was (int). Another way to do the same thing in C++ is to use the functional notation preceding
the expression to be converted by the type and enclosing the expression between parentheses:
i = int (f);
sizeof
This operator accepts one parameter, which can be either a type or a variable, and returns the size in bytes of that type
or object:
x = sizeof (char);
Here, x is assigned the value 1, because char is a type with a size of one byte.
The value returned by sizeof is a compile-time constant, so it is always determined before program execution.
Other operators
Later in these tutorials, we will see a few more operators, like the ones referring to pointers or the specifcs for object-
oriented programming.
Precedence of operators
A single expression may have multiple operators. For example:
x = 5 + 7 %
2;
In C++, the above expression always assigns 6 to variable x, because the % operator has a higher precedence than the
+ operator, and is always evaluated before. Parts of the expressions can be enclosed in parenthesis to override this
precedence order, or to make explicitly clear the intended efect. Notice the diference:
http://www.cplusplus.com/doc/tutorial/operators/[03/12/2018 00:50:24]
Operators - C++ Tutorials
x = (5 + 7) % 2; // x = 0
From greatest to smallest priority, C++ operators are evaluated in the following order:
Level Precedence group Operator Description Grouping
1 Scope :: scope qualifer Left-to-right
++ -- postfx increment / decrement
() functional forms
2 Postfx (unary) Left-to-right
[] subscript
. -> member access
++ -- prefx increment / decrement
~ ! bitwise NOT / logical NOT
+ - unary prefx
3 Prefx (unary) & * reference / dereference Right-to-left
new delete allocation / deallocation
sizeof parameter pack
(type) C-style type-casting
4 Pointer-to-member .* ->* access pointer Left-to-right
5 Arithmetic: scaling * / % multiply, divide, modulo Left-to-right
6 Arithmetic: addition + - addition, subtraction Left-to-right
7 Bitwise shift << >> shift left, shift right Left-to-right
8 Relational < > <= >= comparison operators Left-to-right
9 Equality == != equality / inequality Left-to-right
10 And & bitwise AND Left-to-right
11 Exclusive or ^ bitwise XOR Left-to-right
12 Inclusive or | bitwise OR Left-to-right
13 Conjunction && logical AND Left-to-right
14 Disjunction || logical OR Left-to-right
= *= /= %= += -
= assignment / compound
15 Assignment-level expressions >>= <<= &= ^= assignment Right-to-left
|=
?: conditional operator
16 Sequencing , comma separator Left-to-right
When an expression has two operators with the same precedence level, grouping determines which one is evaluated
frst: either left-to-right or right-to-left.
Enclosing all sub-statements in parentheses (even those unnecessary because of their precedence) improves code
readability.
Previous: Next:
Constants Basic Input/Output
Index
http://www.cplusplus.com/doc/tutorial/operators/[03/12/2018 00:50:24]
Operators - C++ Tutorials
http://www.cplusplus.com/doc/tutorial/operators/[03/12/2018 00:50:24]
Basic Input/Output - C++ Tutorials
Go
C++
Information
Tutorials
Reference
Articles
Forum
Basic Input/Output
C++ Language The example programs of the previous sections provided little interaction with the user, if any at all. They simply
Ascii printed simple values on screen, but the standard library provides many additional ways to interact with the user via its
Codes input/output features. This section will present a short introduction to some of the most useful.
Boolean Operations
Numerical Bases C++ uses a convenient abstraction called streams to perform input and output operations in sequential media such as
the screen, the keyboard or a fle. A stream is an entity where a program can either insert or extract characters
to/from. There is no need to know details about the media associated to the stream or any of its internal specifcations.
All we need to know is that streams are a source/destination of characters, and that these characters are
Introduction:
provided/accepted sequentially (i.e., one after another).
Compilers
Basics of C++: The standard library defnes a handful of stream objects that can be used to access what are considered the standard
Structure of a sources and destinations of characters by the environment where the program runs:
program
Variables and types stream description
Consants cin standard input stream
Operators cout standard output stream
Basic Input/Output cerr standard error (output) stream
Program sructure: standard logging (output)
clog
Statements and fow stream
control
Functions We are going to see in more detail only cout and cin (the standard output and input streams); cerr and clog are also
Overloads and output streams, so they essentially work like cout, with the only diference being that they identify streams for specifc
templates
purposes: error messages and logging; which, in many cases, in most environment setups, they actually do the exact
same thing: they print on screen, although they can also be individually redirected.
Name
visibility
Standard output (cout)
Arrays
On most program environments, the standard output by default is the screen, and the C++ stream object defned to
Character sequences
access it is cout.
Pointers
Dynamic memory For formatted output operations, cout is used together with the insertion operator, which is written as << (i.e., two
Data "less than" signs).
sructures
Other data 1 cout << "Output sentence"; // prints Output sentence on screen
2 cout << 120; // prints number 120 on screen
types 3 cout << x; // prints the value of x on screen
Classes:
http://www.cplusplus.com/doc/tutorial/basic_io/[03/12/2018 00:50:46]
Basic Input/Output - C++ Tutorials
Classes (I)
Classes (II) The << operator inserts the data that follows it into the stream that precedes it. In the examples above, it inserted the
Special members literal string Output sentence, the number 120, and the value of variable x into the standard output stream cout.
Notice that the sentence in the frst statement is enclosed in double quotes (") because it is a string literal, while in the
last one, x is not. The double quoting is what makes the diference; when the text is enclosed between them, the text
Polymorphism
is printed literally; when they are not, the text is interpreted as the identifer of a variable, and its value is printed
instead. For example, these two sentences have very diferent results:
Type conversions
Exceptions 1 cout << "Hello"; // prints Hello
Preprocessor directives 2 cout << Hello; // prints the content of variable Hello
Standard library:
Input/output with
Multiple insertion operations (<<) may be chained in a single statement:
fles
cout << "This " << " is a " << "single C++
satement";
This last statement would print the text This is a single C++ satement. Chaining insertions is especially useful to
mix literals and variables in a single statement:
cout << "I am " << age << " years old and my zipcode is " <<
zipcode;
Assuming the age variable contains the value 24 and the zipcode variable contains 90064, the output of the previous
statement would be:
The output would be in a single line, without any line breaks in between. Something like:
Firs sentence.
Second sentence.
Third sentence.
Alternatively, the endl manipulator can also be used to break lines. For example:
http://www.cplusplus.com/doc/tutorial/basic_io/[03/12/2018 00:50:46]
Basic Input/Output - C++ Tutorials
Firs sentence.
Second sentence.
The endl manipulator produces a newline character, exactly as the insertion of '\n' does; but it also has an additional
behavior: the stream's bufer (if any) is fushed, which means that the output is requested to be physically written to
the device, if it wasn't already. This afects mainly fully bufered streams, and cout is (generally) not a fully bufered
stream. Still, it is generally a good idea to use endl only when fushing the stream would be a feature and'\n' when it
would not. Bear in mind that a fushing operation incurs a certain overhead, and on some devices it may produce a
delay.
For formatted input operations, cin is used together with the extraction operator, which is written as >> (i.e., two
"greater than" signs). This operator is then followed by the variable where the extracted data is stored. For example:
1 int age;
2 cin >>
age;
The frst statement declares a variable of type int called age, and the second extracts from cin a value to be stored in
it. This operation makes the program wait for input from cin; generally, this means that the program will wait for the
user to enter some sequence with the keyboard. In this case, note that the characters introduced using the keyboard
are only transmitted to the program when the ENTER (or RETURN) key is pressed. Once the statement with the
extraction operation on cin is reached, the program will wait for as long as needed until some input is introduced.
The extraction operation on cin uses the type of the variable after the >> operator to determine how it interprets the
characters read from the input; if it is an integer, the format expected is a series of digits, if a string a sequence of
characters, etc.
As you can see, extracting from cin seems to make the task of getting input from the standard input pretty simple and
straightforward. But this method also has a big drawback. What happens in the example above if the user enters
something else that cannot be interpreted as an integer? Well, in this case, the extraction operation fails. And this, by
default, lets the program continue without setting a value for variable i, producing undetermined results if the value of
i is used later.
http://www.cplusplus.com/doc/tutorial/basic_io/[03/12/2018 00:50:46]
Basic Input/Output - C++ Tutorials
This is very poor program behavior. Most programs are expected to behave in an expected manner no matter what the
user types, handling invalid values appropriately. Only very simple programs should rely on values extracted directly
from cin without further checking. A little later we will see how stringstreams can be used to have better control over
user input.
Extractions on cin can also be chained to request more than one datum in a single statement:
1 cin >>
2 a;
cin >>
b;
In both cases, the user is expected to introduce two values, one for variable a, and another for variable b. Any kind of
space is used to separate two consecutive input operations; this may either be a space, a tab, or a new-line character.
1 sring mysring;
2 cin >>
mysring;
However, cin extraction always considers spaces (whitespaces, tabs, new-line...) as terminating the value being
extracted, and thus extracting a string means to always extract a single word, not a phrase or an entire sentence.
To get an entire line from cin, there exists a function, called getline, that takes the stream (cin) as frst argument,
and the string variable as second. For example:
Notice how in both calls to getline, we used the same string identifer (mysr). What the program does in the second
call is simply replace the previous content with the new one that is introduced.
The standard behavior that most users expect from a console program is that each time the program queries the user
for input, the user introduces the feld, and then presses ENTER (or RETURN). That is to say, input is generally expected
http://www.cplusplus.com/doc/tutorial/basic_io/[03/12/2018 00:50:46]
Basic Input/Output - C++ Tutorials
to happen in terms of lines on console programs, and this can be achieved by using getline to obtain input from the
user. Therefore, unless you have a strong reason not to, you should always use getline to get input in your console
programs instead of extracting from cin.
stringstream
The standard header <ssream> defnes a type called sringsream that allows a string to be treated as a stream, and
thus allowing extraction or insertion operations from/to strings in the same way as they are performed on cin and
cout. This feature is most useful to convert strings to numerical values and vice versa. For example, in order to extract
an integer from a string we can write:
This declares a sring with initialized to a value of "1204", and a variable of type int. Then, the third line uses this
variable to extract from a sringsream constructed from the string. This piece of code stores the numerical value1204
in the variable called myint.
In this example, we acquire numeric values from the standard input indirectly: Instead of extracting numeric values
directly from cin, we get lines from it into a string object (mysr), and then we extract the values from this string into
the variables price and quantity. Once these are numerical values, arithmetic operations can be performed on them,
such as multiplying them to obtain a total price.
With this approach of getting entire lines and extracting their contents, we separate the process of getting user input
from its interpretation as data, allowing the input process to be what the user expects, and at the same time gaining
more control over the transformation of its content into useful data by the program.
Previous: Next:
Operators Statements and fow control
Index
http://www.cplusplus.com/doc/tutorial/basic_io/[03/12/2018 00:50:46]
Basic Input/Output - C++ Tutorials
http://www.cplusplus.com/doc/tutorial/basic_io/[03/12/2018 00:50:46]
Statements and flow control - C++ Tutorials
Go
C++
Information
Tutorials
Reference
Articles
Forum
http://www.cplusplus.com/doc/tutorial/control/[03/12/2018 00:51:10]
Statements and flow control - C++ Tutorials
Selection statements with if can also specify what happens when the condition is not fulflled, by using the else
keyword to introduce an alternative statement. Its syntax is:
where satement1 is executed in case condition is true, and in case it is not, satement2 is executed.
For example:
1 if (x == 100)
2 cout << "x is 100";
3 else
4 cout << "x is not
100";
This prints x is 100, if indeed x has a value of 100, but if it does not, and only if it does not, it printsx is not 100
instead.
Several if + else structures can be concatenated with the intention of checking a range of values. For example:
1 if (x > 0)
2 cout << "x is
3 positive";
4 else if (x < 0)
5 cout << "x is
6 negative";
else
cout << "x is 0";
This prints whether x is positive, negative, or zero by concatenating two if-else structures. Again, it would have also
been possible to execute more than a single statement per case by grouping them into blocks enclosed in braces: {}.
http://www.cplusplus.com/doc/tutorial/control/[03/12/2018 00:51:10]
Statements and flow control - C++ Tutorials
The while-loop simply repeats satement while expression is true. If, after any execution of satement, expression is
no longer true, the loop ends, and the program continues right after the loop. For example, let's have a look at a
countdown using a while-loop:
The frst statement in main sets n to a value of 10. This is the frst number in the countdown. Then the while-loop
begins: if this value fulflls the condition n>0 (that n is greater than zero), then the block that follows the condition is
executed, and repeated for as long as the condition (n>0) remains being true.
The whole process of the previous program can be interpreted according to the following script (beginning in main):
1. n is assigned a value
2. The while condition is checked (n>0). At this point there are two possibilities:
condition is true: the statement is executed (to step 3)
condition is false: ignore statement and continue after it (to step 5)
3. Execute statement:
cout << n << ", ";
--n;
(prints the value of n and decreases n by 1)
4. End of block. Return automatically to step 2.
5. Continue the program right after the block:
print liftof! and end the program.
A thing to consider with while-loops is that the loop should end at some point, and thus the statement shall alter values
checked in the condition in some way, so as to force it to become false at some point. Otherwise, the loop will continue
looping forever. In this case, the loop includes --n, that decreases the value of the variable that is being evaluated in
the condition (n) by one - this will eventually make the condition (n>0) false after a certain number of loop iterations.
To be more specifc, after 10 iterations, n becomes 0, making the condition no longer true, and ending the while-loop.
Note that the complexity of this loop is trivial for a computer, and so the whole countdown is performed instantly,
without any practical delay between elements of the count (if interested, see sleep_for for a countdown example with
delays).
It behaves like a while-loop, except that condition is evaluated after the execution of satement instead of before,
guaranteeing at least one execution of satement, even if condition is never fulflled. For example, the following
example program echoes any text the user introduces until the user enters goodbye:
http://www.cplusplus.com/doc/tutorial/control/[03/12/2018 00:51:10]
Statements and flow control - C++ Tutorials
The do-while loop is usually preferred over a while-loop when the satement needs to be executed at least once, such as
when the condition that is checked to end of the loop is determined within the loop statement itself. In the previous
example, the user input within the block is what will determine if the loop ends. And thus, even if the user wants to
end the loop as soon as possible by entering goodbye, the block in the loop needs to be executed at least once to
prompt for input, and the condition can, in fact, only be determined after it is executed.
Like the while-loop, this loop repeats satement while condition is true. But, in addition, the for loop provides specifc
locations to contain an initialization and an increase expression, executed before the loop begins the frst time,
and after each iteration, respectively. Therefore, it is especially useful to use counter variables as condition.
1. initialization is executed. Generally, this declares a counter variable, and sets it to some initial value. This is
executed a single time, at the beginning of the loop.
2. condition is checked. If it is true, the loop continues; otherwise, the loop ends, andsatement is skipped, going
directly to step 5.
3. satement is executed. As usual, it can be either a single statement or a block enclosed in curly braces{ }.
4. increase is executed, and the loop gets back to step 2.
5. the loop ends: execution continues by the next statement after it.
The three felds in a for-loop are optional. They can be left empty, but in all cases the semicolon signs between them
are required. For example, for (;n<10;) is a loop without initialization or increase (equivalent to a while-loop); and
for (;n<10;++n) is a loop with increase, but no initialization (maybe because the variable was already initialized
before the loop). A loop with no condition is equivalent to a loop with true as condition (i.e., an infnite loop).
http://www.cplusplus.com/doc/tutorial/control/[03/12/2018 00:51:10]
Statements and flow control - C++ Tutorials
Because each of the felds is executed in a particular time in the life cycle of a loop, it may be useful to execute more
than a single expression as any of initialization, condition, or statement. Unfortunately, these are not statements, but
rather, simple expressions, and thus cannot be replaced by a block. As expressions, they can, however, make use of
the comma operator (,): This operator is an expression separator, and can separate multiple expressions where only
one is generally expected. For example, using it, it would be possible for a for loop to handle two counter variables,
initializing and increasing both:
This loop will execute 50 times if neither n or i are modifed within the loop:
n starts with a value of 0, and i with 100, the condition is n!=i (i.e., that n is not equal to i). Because n is increased by
one, and i decreased by one on each iteration, the loop's condition will become false after the 50th iteration, when both
n and i are equal to 50.
This kind of for loop iterates over all the elements in range, where declaration declares some variable able to take
the value of an element in this range. Ranges are sequences of elements, including arrays, containers, and any other
type supporting the functions begin and end; Most of these types have not yet been introduced in this tutorial, but we
are already acquainted with at least one kind of range: strings, which are sequences of characters.
Note how what precedes the colon (:) in the for loop is the declaration of a char variable (the elements in a string are
of type char). We then use this variable, c, in the statement block to represent the value of each of the elements in the
range.
This loop is automatic and does not require the explicit declaration of any counter variable.
http://www.cplusplus.com/doc/tutorial/control/[03/12/2018 00:51:10]
Statements and flow control - C++ Tutorials
Range based loops usually also make use of type deduction for the type of the elements with auto. Typically, the
range-based loop above can also be written as:
Here, the type of c is automatically deduced as the type of the elements in sr.
Jump statements
Jump statements allow altering the fow of a program by performing jumps to specifc locations.
The destination point is identifed by a label, which is then used as an argument for the goto statement. A label is
http://www.cplusplus.com/doc/tutorial/control/[03/12/2018 00:51:10]
Statements and flow control - C++ Tutorials
goto is generally deemed a low-level feature, with no particular use cases in modern higher-level programming
paradigms generally used with C++. But, just as an example, here is a version of our countdown loop using goto:
switch (expression)
{
case consant1:
group-of-satements-1;
break;
case consant2:
group-of-satements-2;
break;
.
.
.
default:
default-group-of-satements
}
It works in the following way: switch evaluates expression and checks if it is equivalent to consant1; if it is, it
executes group-of-satements-1 until it fnds the break statement. When it fnds this break statement, the program
jumps to the end of the entire switch statement (the closing brace).
If expression was not equal to consant1, it is then checked against consant2. If it is equal to this, it executes group-
of-satements-2 until a break is found, when it jumps to the end of the switch.
Finally, if the value of expression did not match any of the previously specifed constants (there may be any number of
these), the program executes the statements included after the default: label, if it exists (since it is optional).
Both of the following code fragments have the same behavior, demonstrating the if-else equivalent of a switch
statement:
http://www.cplusplus.com/doc/tutorial/control/[03/12/2018 00:51:10]
Statements and flow control - C++ Tutorials
} }
The switch statement has a somewhat peculiar syntax inherited from the early times of the frst C compilers, because
it uses labels instead of blocks. In the most typical use (shown above), this means that break statements are needed
after each group of statements for a particular label. If break is not included, all statements following the case
(including those under any other labels) are also executed, until the end of the switch block or a jump statement (such
as break) is reached.
If the example above lacked the break statement after the frst group for case one, the program would not jump
automatically to the end of the switch block after printing x is 1, and would instead continue executing the
statements in case two (thus printing also x is 2). It would then continue doing so until a break statement is
encountered, or the end of the switch block. This makes unnecessary to enclose the statements for each case in
braces {}, and can also be useful to execute the same group of statements for diferent possible values. For example:
1 switch (x) {
2 case 1:
3 case 2:
4 case 3:
5 cout << "x is 1, 2 or 3";
6 break;
7 default:
8 cout << "x is not 1, 2 nor
9 3";
}
Notice that switch is limited to compare its evaluated expression against labels that are constant expressions. It is not
possible to use variables as labels or ranges, because they are not valid C++ constant expressions.
To check for ranges or values that are not constant, it is better to use concatenations of if and else if statements.
Previous: Next:
Basic Input/Output Functions
Index
http://www.cplusplus.com/doc/tutorial/control/[03/12/2018 00:51:10]
Functions - C++ Tutorials
Go
C++
Information
Tutorials
Reference
Articles
Forum
Functions
C++ Language Functions allow to structure programs in segments of code to perform individual tasks.
Ascii
Codes In C++, a function is a group of statements that is given a name, and which can be called from some point of the
Boolean Operations program. The most common syntax to defne a function is:
Numerical Bases
type name ( parameter1, parameter2, ...) { satements }
Where:
Introduction:
- type is the type of the value returned by the function.
Compilers - name is the identifer by which the function can be called.
Basics of C++: - parameters (as many as needed): Each parameter consists of a type followed by an identifer, with each parameter
Structure of a being separated from the next by a comma. Each parameter looks very much like a regular variable declaration (for
program example: int x), and in fact acts within the function as a regular variable which is local to the function. The purpose of
Variables and types parameters is to allow passing arguments to the function from the location where it is called from.
Consants
- satements is the function's body. It is a block of statements surrounded by braces { } that specify what the function
actually does.
Operators
Basic Input/Output Let's have a look at an example:
Program sructure:
Statements and fow 1 // function example The result is 8
control
2 #include <iosream>
3 using namespace sd;
Functions 4
5 int addition (int a, int b)
Overloads and 6 {
templates 7 int r;
8 r=a+b;
Name 9 return r;
10 }
visibility 11
12 int main ()
13 {
Arrays 14 int z;
Character sequences 15 z = addition (5,3);
16 cout << "The result is " << z;
Pointers 17 }
Dynamic memory
Data
sructures This program is divided in two functions: addition and main. Remember that no matter the order in which they are
Other data defned, a C++ program always starts by calling main. In fact, main is the only function called automatically, and the
code in any other function is only executed if its function is called from main (directly or indirectly).
types
Classes:
In the example above, main begins by declaring the variable z of type int, and right after that, it performs the frst
http://www.cplusplus.com/doc/tutorial/functions/[03/12/2018 00:51:32]
Functions - C++ Tutorials
Classes (I) function call: it calls addition. The call to a function follows a structure very similar to its declaration. In the example
Classes (II) above, the call to addition can be compared to its defnition just a few lines earlier:
Special members
Polymorphism
Type conversions
Exceptions The parameters in the function declaration have a clear correspondence to the arguments passed in the function call.
Preprocessor directives The call passes two values, 5 and 3, to the function; these correspond to the parameters a and b, declared for function
Standard library: addition.
Input/output with
At the point at which the function is called from within main, the control is passed to function addition: here,
fles
execution of main is stopped, and will only resume once the addition function ends. At the moment of the function
call, the value of both arguments (5 and 3) are copied to the local variables int a and int b within the function.
Then, inside addition, another local variable is declared (int r), and by means of the expression r=a+b, the result of
a plus b is assigned to r; which, for this case, where a is 5 and b is 3, means that 8 is assigned to r.
return
r;
Ends function addition, and returns the control back to the point where the function was called; in this case: to
function main. At this precise moment, the program resumes its course on main returning exactly at the same point at
which it was interrupted by the call to addition. But additionally, because addition has a return type, the call is
evaluated as having a value, and this value is the value specifed in the return statement that ended addition: in this
particular case, the value of the local variable r, which at the moment of the return statement had a value of 8.
Therefore, the call to addition is an expression with the value returned by the function, and in this case, that value, 8,
is assigned to z. It is as if the entire function call (addition(5,3)) was replaced by the value it returns (i.e., 8).
A function can actually be called multiple times within a program, and its argument is naturally not limited just to
literals:
http://www.cplusplus.com/doc/tutorial/functions/[03/12/2018 00:51:32]
Functions - C++ Tutorials
12 int main ()
13 {
14 int x=5, y=3, z;
15 z = subtraction (7,2);
16 cout << "The frs result is " << z << '\n';
17 cout << "The second result is " <<
18 subtraction (7,2) << '\n';
19 cout << "The third result is " << subtraction
20 (x,y) << '\n';
21 z= 4 + subtraction (x,y);
cout << "The fourth result is " << z << '\n';
}
Similar to the addition function in the previous example, this example defnes a subtract function, that simply returns
the diference between its two parameters. This time, main calls this function several times, demonstrating more
possible ways in which a function can be called.
Let's examine each of these calls, bearing in mind that each function call is itself an expression that is evaluated as the
value it returns. Again, you can think of it as if the function call was itself replaced by the returned value:
1 z = subtraction (7,2);
2 cout << "The frs result is " <<
z;
If we replace the function call by the value it returns (i.e., 5), we would have:
1 z = 5;
2 cout << "The frs result is " <<
z;
as:
cout << "The second result is " <<
5;
The arguments passed to subtraction are variables instead of literals. That is also valid, and works fne. The function is
called with the values x and y have at the moment of the call: 5 and 3 respectively, returning 2 as result.
z = 4 + subtraction (x,y);
http://www.cplusplus.com/doc/tutorial/functions/[03/12/2018 00:51:32]
Functions - C++ Tutorials
The only addition being that now the function call is also an operand of an addition operation. Again, the result is the
same as if the function call was replaced by its result: 6. Note, that thanks to the commutative property of additions,
the above can also be written as:
z = subtraction (x,y) +
4;
With exactly the same result. Note also that the semicolon does not necessarily go after the function call, but, as
always, at the end of the whole statement. Again, the logic behind may be easily seen again by replacing the function
calls by their returned value:
Requires the declaration to begin with a type. This is the type of the value returned by the function. But what if the
function does not need to return a value? In this case, the type to be used is void, which is a special type to represent
the absence of value. For example, a function that simply prints a message may not need to return any value:
void can also be used in the function's parameter list to explicitly specify that the function takes no actual parameters
when called. For example, printmessage could have been declared as:
In C++, an empty parameter list can be used instead of void with same meaning, but the use of void in the argument
list was popularized by the C language, where this is a requirement.
Something that in no case is optional are the parentheses that follow the function name, neither in its declaration nor
when calling it. And even when the function takes no parameters, at least an empty pair of parentheses shall always be
appended to the function name. See how printmessage was called in an earlier example:
printmessage ();
http://www.cplusplus.com/doc/tutorial/functions/[03/12/2018 00:51:32]
Functions - C++ Tutorials
The parentheses are what diferentiate functions from other kinds of declarations or statements. The following would
not call the function:
printmessage;
Well, there is a catch: If the execution of main ends normally without encountering a return statement the compiler
assumes the function ends with an implicit return statement:
return
0;
Note that this only applies to function main for historical reasons. All other functions with a return type shall end with a
proper return statement that includes a return value, even if this is never used.
When main returns zero (either implicitly or explicitly), it is interpreted by the environment as that the program ended
successfully. Other values may be returned by main, and some environments give access to that value to the caller in
some way, although this behavior is not required nor necessarily portable between platforms. The values for main that
are guaranteed to be interpreted in the same way on all platforms are:
value description
0 The program was successful
The program was successful (same as
EXIT_SUCCESS above).
This value is defned in header <csdlib>.
The program failed.
EXIT_FAILURE
This value is defned in header <csdlib>.
Because the implicit return 0; statement for main is a tricky exception, some authors consider it good practice to
explicitly write the statement.
In this case, function addition is passed 5 and 3, which are copies of the values of x and y, respectively. These values
(5 and 3) are used to initialize the variables set as parameters in the function's defnition, but any modifcation of these
variables within the function has no efect on the values of the variables x and y outside it, because x and y were
themselves not passed to the function on the call, but only copies of their values at that moment.
http://www.cplusplus.com/doc/tutorial/functions/[03/12/2018 00:51:32]
Functions - C++ Tutorials
In certain cases, though, it may be useful to access an external variable from within a function. To do that, arguments
can be passed by reference, instead of by value. For example, the function duplicate in this code duplicates the value
of its three arguments, causing the variables used as arguments to actually be modifed by the call:
To gain access to its arguments, the function declares its parameters as references. In C++, references are indicated
with an ampersand (&) following the parameter type, as in the parameters taken by duplicate in the example above.
When a variable is passed by reference, what is passed is no longer a copy, but the variable itself, the variable
identifed by the function parameter, becomes somehow associated with the argument passed to the function, and any
modifcation on their corresponding local variables within the function are refected in the variables passed as
arguments in the call.
In fact, a, b, and c become aliases of the arguments passed on the function call (x, y, and z) and any change on a
within the function is actually modifying variable x outside the function. Any change on b modifes y, and any change on
c modifes z. That is why when, in the example, function duplicate modifes the values of variables a, b, and c, the
values of x, y, and z are afected.
The variables would not be passed by reference, but by value, creating instead copies of their values. In this case, the
http://www.cplusplus.com/doc/tutorial/functions/[03/12/2018 00:51:32]
Functions - C++ Tutorials
output of the program would have been the values of x, y, and z without being modifed (i.e., 1, 3, and 7).
This function takes two strings as parameters (by value), and returns the result of concatenating them. By passing the
arguments by value, the function forces a and b to be copies of the arguments passed to the function when it is called.
And if these are long strings, it may mean copying large quantities of data just for the function call.
But this copy can be avoided altogether if both parameters are made references:
Arguments by reference do not require a copy. The function operates directly on (aliases of) the strings passed as
arguments, and, at most, it might mean the transfer of certain pointers to the function. In this regard, the version of
concatenate taking references is more efcient than the version taking values, since it does not need to copy
expensive-to-copy strings.
On the fip side, functions with reference parameters are generally perceived as functions that modify the arguments
passed, because that is why reference parameters are actually for.
The solution is for the function to guarantee that its reference parameters are not going to be modifed by this function.
This can be done by qualifying the parameters as constant:
By qualifying them as cons, the function is forbidden to modify the values of neither a nor b, but can actually access
their values as references (aliases of the arguments), without having to make actual copies of the strings.
Therefore, cons references provide functionality similar to passing arguments by value, but with an increased efciency
for parameters of large types. That is why they are extremely popular in C++ for arguments of compound types. Note
though, that for most fundamental types, there is no noticeable diference in efciency, and in some cases, const
references may even be less efcient!
Inline functions
Calling a function generally causes a certain overhead (stacking arguments, jumps, etc...), and thus for very short
functions, it may be more efcient to simply insert the code of the function where it is called, instead of performing the
process of formally calling a function.
http://www.cplusplus.com/doc/tutorial/functions/[03/12/2018 00:51:32]
Functions - C++ Tutorials
Preceding a function declaration with the inline specifer informs the compiler that inline expansion is preferred over
the usual function call mechanism for a specifc function. This does not change at all the behavior of a function, but is
merely used to suggest the compiler that the code generated by the function body shall be inserted at each point the
function is called, instead of being invoked with a regular function call.
For example, the concatenate function above may be declared inline as:
This informs the compiler that when concatenate is called, the program prefers the function to be expanded inline,
instead of performing a regular call. inline is only specifed in the function declaration, not when it is called.
Note that most compilers already optimize code to generate inline functions when they see an opportunity to improve
efciency, even if not explicitly marked with the inline specifer. Therefore, this specifer merely indicates the compiler
that inline is preferred for this function, although the compiler is free to not inline it, and optimize otherwise. In C++,
optimization is a task delegated to the compiler, which is free to generate any code for as long as the resulting
behavior is the one specifed by the code.
In this example, there are two calls to function divide. In the frst one:
divide (12)
The call only passes one argument to the function, even though the function has two parameters. In this case, the
function assumes the second parameter to be 2 (notice the function defnition, which declares its second parameter as
int b=2). Therefore, the result is 6.
http://www.cplusplus.com/doc/tutorial/functions/[03/12/2018 00:51:32]
Functions - C++ Tutorials
divide (20,4)
The call passes two arguments to the function. Therefore, the default value for b (int b=2) is ignored, and b takes the
value passed as argument, that is 4, yielding a result of 5.
Declaring functions
In C++, identifers can only be used in expressions once they have been declared. For example, some variable x
cannot be used before being declared with a statement, such as:
int
x;
The same applies to functions. Functions cannot be called before they are declared. That is why, in all the previous
examples of functions, the functions were always defned before the main function, which is the function from where
the other functions were called. If main were defned before the other functions, this would break the rule that functions
shall be declared before being used, and thus would not compile.
The prototype of a function can be declared without actually defning the function completely, giving just enough details
to allow the types involved in a function call to be known. Naturally, the function shall be defned somewhere else, like
later in the code. But at least, once declared like this, it can already be called.
The declaration shall include all types involved (the return type and the type of its arguments), using the same syntax
as used in the defnition of the function, but replacing the body of the function (the block of statements) with an ending
semicolon.
The parameter list does not need to include the parameter names, but only their types. Parameter names can
nevertheless be specifed, but they are optional, and do not need to necessarily match those in the function defnition.
For example, a function called protofunction with two int parameters can be declared with either of these statements:
Anyway, including a name for each parameter always improves legibility of the declaration.
http://www.cplusplus.com/doc/tutorial/functions/[03/12/2018 00:51:32]
Functions - C++ Tutorials
25
26 void even (int x)
27 {
28 if ((x%2)==0) cout << "It is even.\n";
29 else odd (x);
}
This example is indeed not an example of efciency. You can probably write yourself a version of this program with half
the lines of code. Anyway, this example illustrates how functions can be declared before its defnition:
Declare the prototype of the functions. They already contain all what is necessary to call them, their name, the types of
their argument, and their return type (void in this case). With these prototype declarations in place, they can be called
before they are entirely defned, allowing for example, to place the function from where they are called (main) before
the actual defnition of these functions.
But declaring functions before being defned is not only useful to reorganize the order of functions within the code. In
some cases, such as in this particular case, at least one of the declarations is required, because odd and even are
mutually called; there is a call to even in odd and a call to odd in even. And, therefore, there is no way to structure the
code so that odd is defned before even, and even before odd.
Recursivity
Recursivity is the property that functions have to be called by themselves. It is useful for some tasks, such as sorting
elements, or calculating the factorial of numbers. For example, in order to obtain the factorial of a number (n!) the
mathematical formula would be:
5! = 5 * 4 * 3 * 2 * 1 = 120
And a recursive function to calculate this in C++ could be:
Notice how in function factorial we included a call to itself, but only if the argument passed was greater than 1, since,
http://www.cplusplus.com/doc/tutorial/functions/[03/12/2018 00:51:32]
Functions - C++ Tutorials
otherwise, the function would perform an infnite recursive loop, in which once it arrived to 0, it would continue
multiplying by all the negative numbers (probably provoking a stack overfow at some point during runtime).
Previous: Next:
Statements and fow control Overloads and templates
Index
http://www.cplusplus.com/doc/tutorial/functions/[03/12/2018 00:51:32]
Overloads and templates - C++ Tutorials
Go
C++
Information
Tutorials
Reference
Articles
Forum
http://www.cplusplus.com/doc/tutorial/functions2/[03/12/2018 00:51:54]
Overloads and templates - C++ Tutorials
Classes (I)
Classes (II)
Function templates
Special members Overloaded functions may have the same defnition. For example:
Friendship and inheritance
1 // overloaded functions 30
Polymorphism 2 #include <iosream> 2.5
3 using namespace sd;
4
Type conversions 5 int sum (int a, int b)
Exceptions 6 {
7 return a+b;
Preprocessor directives 8 }
9
Standard library: 10 double sum (double a, double b)
Input/output with 11 {
12 return a+b;
fles 13 }
14
15 int main ()
16 {
17 cout << sum (10,20) << '\n';
18 cout << sum (1.0,1.5) << '\n';
19 return 0;
20 }
Here, sum is overloaded with diferent parameter types, but with the exact same body.
The function sum could be overloaded for a lot of types, and it could make sense for all of them to have the same body.
For cases such as this, C++ has the ability to defne functions with generic types, known as function templates.
Defning a function template follows the same syntax as a regular function, except that it is preceded by the template
keyword and a series of template parameters enclosed in angle-brackets <>:
It makes no diference whether the generic type is specifed with keyword class or keyword typename in the template
argument list (they are 100% synonyms in template declarations).
In the code above, declaring SomeType (a generic type within the template parameters enclosed in angle-brackets)
allows SomeType to be used anywhere in the function defnition, just as any other type; it can be used as the type for
parameters, as return type, or to declare new variables of this type. In all cases, it represents a generic type that will
be determined on the moment the template is instantiated.
Instantiating a template is applying the template to create a function using particular types or values for its template
parameters. This is done by calling the function template, with the same syntax as calling a regular function, but
specifying the template arguments enclosed in angle brackets:
x = sum<int>(10,20);
http://www.cplusplus.com/doc/tutorial/functions2/[03/12/2018 00:51:54]
Overloads and templates - C++ Tutorials
The function sum<int> is just one of the possible instantiations of function template sum. In this case, by using int as
template argument in the call, the compiler automatically instantiates a version of sum where each occurrence of
SomeType is replaced by int, as if it was defned as:
1 // function template 11
2 #include <iosream> 2.5
3 using namespace sd;
4
5 template <class T>
6 T sum (T a, T b)
7 {
8 T result;
9 result = a + b;
10 return result;
11 }
12
13 int main () {
14 int i=5, j=6, k;
15 double f=2.0, g=0.5, h;
16 k=sum<int>(i,j);
17 h=sum<double>(f,g);
18 cout << k << '\n';
19 cout << h << '\n';
20 return 0;
21 }
In this case, we have used T as the template parameter name, instead of SomeType. It makes no diference, and T is
actually a quite common template parameter name for generic types.
In the example above, we used the function template sum twice. The frst time with arguments of type int, and the
second one with arguments of type double. The compiler has instantiated and then called each time the appropriate
version of the function.
Note also how T is also used to declare a local variable of that (generic) type within sum:
T
result;
Therefore, result will be a variable of the same type as the parameters a and b, and as the type returned by the
function.
In this specifc case where the generic type T is used as a parameter for sum, the compiler is even able to deduce the
data type automatically without having to explicitly specify it within angle brackets. Therefore, instead of explicitly
specifying the template arguments with:
1 k = sum<int> (i,j);
2 h = sum<double> (f,g);
http://www.cplusplus.com/doc/tutorial/functions2/[03/12/2018 00:51:54]
Overloads and templates - C++ Tutorials
1 k = sum (i,j);
2 h = sum (f,g);
without the type enclosed in angle brackets. Naturally, for that, the type shall be unambiguous. If sum is called with
arguments of diferent types, the compiler may not be able to deduce the type of T automatically.
Templates are a powerful and versatile feature. They can have multiple template parameters, and the function can still
use regular non-templated types. For example:
Note that this example uses automatic template parameter deduction in the call to are_equal:
are_equal(10,10.0)
Is equivalent to:
are_equal<int,double>(10,10.0)
There is no ambiguity possible because numerical literals are always of a specifc type: Unless otherwise specifed with
a sufx, integer literals always produce values of type int, and foating-point literals always produce values of type
double. Therefore 10 has always type int and 10.0 has always type double.
1 // template arguments 20
2 #include <iosream> 30
3 using namespace sd;
4
5 template <class T, int N>
6 T fxed_multiply (T val)
7 {
8 return val * N;
9 }
10
11 int main() {
12 sd::cout << fxed_multiply<int,2>(10) << '\n';
13 sd::cout << fxed_multiply<int,3>(10) << '\n';
14 }
http://www.cplusplus.com/doc/tutorial/functions2/[03/12/2018 00:51:54]
Overloads and templates - C++ Tutorials
The second argument of the fxed_multiply function template is of type int. It just looks like a regular function
parameter, and can actually be used just like one.
But there exists a major diference: the value of template parameters is determined on compile-time to generate a
diferent instantiation of the function fxed_multiply, and thus the value of that argument is never passed during
runtime: The two calls to fxed_multiply in main essentially call two versions of the function: one that always
multiplies by two, and one that always multiplies by three. For that same reason, the second template argument needs
to be a constant expression (it cannot be passed a variable).
Previous: Next:
Functions Name visibility
Index
http://www.cplusplus.com/doc/tutorial/functions2/[03/12/2018 00:51:54]
Name visibility - C++ Tutorials
Go
C++
Information
Tutorials
Reference
Articles
Forum
Name visibility
C++ Language
Ascii Scopes
Codes
Named entities, such as variables, functions, and compound types need to be declared before being used in C++. The
Boolean Operations
point in the program where this declaration happens infuences its visibility:
Numerical Bases
An entity declared outside any block has global scope, meaning that its name is valid anywhere in the code. While an
entity declared within a block, such as a function or a selective statement, has block scope, and is only visible within
Introduction: the specifc block in which it is declared, but not outside it.
Compilers
Basics of C++: Variables with block scope are known as local variables.
Structure of a
For example, a variable declared in the body of a function is a local variable that extends until the end of the the
program
function (i.e., until the brace } that closes the function defnition), but not outside it:
Variables and types
Consants 1 int foo; // global variable
Operators 2
3 int some_function ()
Basic Input/Output 4 {
Program sructure: 5 int bar; // local variable
6 bar = 0;
Statements and fow 7 }
8
control 9 int other_function ()
Functions 10 {
11 foo = 1; // ok: foo is a global variable
Overloads and 12 bar = 2; // wrong: bar is not visible from this
templates 13 function
}
Name
visibility
Compound data types: In each scope, a name can only represent one entity. For example, there cannot be two variables with the same name
Arrays in the same scope:
Character sequences
Pointers 1 int some_function ()
2{
Dynamic memory 3 int x;
Data 4 x = 0;
5 double x; // wrong: name already used in this
sructures 6 scope
7 x = 0.0;
Other data }
types
Classes:
http://www.cplusplus.com/doc/tutorial/namespaces/[03/12/2018 00:52:16]
Name visibility - C++ Tutorials
Classes (I) The visibility of an entity with block scope extends until the end of the block, including inner blocks. Nevertheless, an
Classes (II) inner block, because it is a diferent block, can re-utilize a name existing in an outer scope to refer to a diferent entity;
Special members in this case, the name will refer to a diferent entity only within the inner block, hiding the entity it names outside.
While outside it, it will still refer to the original entity. For example:
Polymorphism
1 // inner block scopes inner block:
2 #include <iosream> x: 50
Type conversions 3 using namespace sd; y: 50
4 outer block:
Exceptions 5 int main () { x: 10
6 int x = 10; y: 50
Preprocessor directives 7 int y = 20;
Standard library: 8 {
9 int x; // ok, inner scope.
Input/output with 10 x = 50; // sets value to inner x
fles 11 y = 50; // sets value to (outer) y
12 cout << "inner block:\n";
13 cout << "x: " << x << '\n';
14 cout << "y: " << y << '\n';
15 }
16 cout << "outer block:\n";
17 cout << "x: " << x << '\n';
18 cout << "y: " << y << '\n';
19 return 0;
20 }
Note that y is not hidden in the inner block, and thus accessing y still accesses the outer variable.
Variables declared in declarations that introduce a block, such as function parameters and variables declared in loops
and conditions (such as those declared on a for or an if) are local to the block they introduce.
Namespaces
Only one entity can exist with a particular name in a particular scope. This is seldom a problem for local names, since
blocks tend to be relatively short, and names have particular purposes within them, such as naming a counter variable,
an argument, etc...
But non-local names bring more possibilities for name collision, especially considering that libraries may declare many
functions, types, and variables, neither of them local in nature, and some of them very generic.
Namespaces allow us to group named entities that otherwise would have global scope into narrower scopes, giving
them namespace scope. This allows organizing the elements of programs into diferent logical scopes referred to by
names.
namespace identifer
{
named_entities
}
Where identifer is any valid identifer and named_entities is the set of variables, types and functions that are
included within the namespace. For example:
1 namespace myNamespace
2{
3 int a, b;
4}
In this case, the variables a and b are normal variables declared within a namespace called myNamespace.
http://www.cplusplus.com/doc/tutorial/namespaces/[03/12/2018 00:52:16]
Name visibility - C++ Tutorials
These variables can be accessed from within their namespace normally, with their identifer (either a or b), but if
accessed from outside the myNamespace namespace they have to be properly qualifed with the scope operator ::. For
example, to access the previous variables from outside myNamespace they should be qualifed like:
1 myNamespace::a
2 myNamespace::b
1 // namespaces 5
2 #include <iosream> 6.2832
3 using namespace sd; 3.1416
4
5 namespace foo
6 {
7 int value() { return 5; }
8 }
9
10 namespace bar
11 {
12 cons double pi = 3.1416;
13 double value() { return 2*pi; }
14 }
15
16 int main () {
17 cout << foo::value() << '\n';
18 cout << bar::value() << '\n';
19 cout << bar::pi << '\n';
20 return 0;
21 }
In this case, there are two functions with the same name: value. One is defned within the namespace foo, and the
other one in bar. No redefnition errors happen thanks to namespaces. Notice also how pi is accessed in an unqualifed
manner from within namespace bar (just as pi), while it is again accessed in main, but here it needs to be qualifed as
bar::pi.
Namespaces can be split: Two segments of a code can be declared in the same namespace:
This declares three variables: a and c are in namespace foo, while b is in namespace bar. Namespaces can even extend
across diferent translation units (i.e., across diferent fles of source code).
using
The keyword using introduces a name into the current declarative region (such as a block), thus avoiding the need to
qualify the name. For example:
1 // using 5
2 #include <iosream> 2.7183
3 using namespace sd; 10
4 3.1416
5 namespace frs
6 {
7 int x = 5;
8 int y = 10;
9 }
10
http://www.cplusplus.com/doc/tutorial/namespaces/[03/12/2018 00:52:16]
Name visibility - C++ Tutorials
11 namespace second
12 {
13 double x = 3.1416;
14 double y = 2.7183;
15 }
16
17 int main () {
18 using frs::x;
19 using second::y;
20 cout << x << '\n';
21 cout << y << '\n';
22 cout << frs::y << '\n';
23 cout << second::x << '\n';
24 return 0;
25 }
Notice how in main, the variable x (without any name qualifer) refers to frs::x, whereas y refers to second::y, just as
specifed by the using declarations. The variables frs::y and second::x can still be accessed, but require fully
qualifed names.
The keyword using can also be used as a directive to introduce an entire namespace:
1 // using 5
2 #include <iosream> 10
3 using namespace sd; 3.1416
4 2.7183
5 namespace frs
6{
7 int x = 5;
8 int y = 10;
9}
10
11 namespace second
12 {
13 double x = 3.1416;
14 double y = 2.7183;
15 }
16
17 int main () {
18 using namespace frs;
19 cout << x << '\n';
20 cout << y << '\n';
21 cout << second::x << '\n';
22 cout << second::y << '\n';
23 return 0;
24 }
In this case, by declaring that we were using namespace frs, all direct uses of x and y without name qualifers were
also looked up in namespace frs.
using and using namespace have validity only in the same block in which they are stated or in the entire source code
fle if they are used directly in the global scope. For example, it would be possible to frst use the objects of one
namespace and then those of another one by splitting the code in diferent blocks:
http://www.cplusplus.com/doc/tutorial/namespaces/[03/12/2018 00:52:16]
Name visibility - C++ Tutorials
15 int main () {
16 {
17 using namespace frs;
18 cout << x << '\n';
19 }
20 {
21 using namespace second;
22 cout << x << '\n';
23 }
24 return 0;
25 }
Namespace aliasing
Existing namespaces can be aliased with new names, with the following syntax:
This introduces direct visibility of all the names of the sd namespace into the code. This is done in these tutorials to
facilitate comprehension and shorten the length of the examples, but many programmers prefer to qualify each of the
elements of the standard library used in their programs. For example, instead of:
Whether the elements in the sd namespace are introduced with using declarations or are fully qualifed on every use
does not change the behavior or efciency of the resulting program in any way. It is mostly a matter of style
preference, although for projects mixing libraries, explicit qualifcation tends to be preferred.
Storage classes
The storage for variables with global or namespace scope is allocated for the entire duration of the program. This is
known as static storage, and it contrasts with the storage for local variables (those declared within a block). These use
what is known as automatic storage. The storage for local variables is only available during the block in which they are
declared; after that, that same storage may be used for a local variable of some other function, or used otherwise.
But there is another substantial diference between variables with static storage and variables with automatic storage:
- Variables with static storage (such as global variables) that are not explicitly initialized are automatically initialized to
zeroes.
- Variables with automatic storage (such as local variables) that are not explicitly initialized are left uninitialized, and
thus have an undetermined value.
http://www.cplusplus.com/doc/tutorial/namespaces/[03/12/2018 00:52:16]
Name visibility - C++ Tutorials
For example:
1 // satic vs automatic sorage 0
2 #include <iosream> 4285838
3 using namespace sd;
4
5 int x;
6
7 int main ()
8{
9 int y;
10 cout << x << '\n';
11 cout << y << '\n';
12 return 0;
13 }
The actual output may vary, but only the value of x is guaranteed to be zero. y can actually contain just about any
value (including zero).
Previous: Next:
Overloads and templates Arrays
Index
http://www.cplusplus.com/doc/tutorial/namespaces/[03/12/2018 00:52:16]
Arrays - C++ Tutorials
Go
C++
Information
Tutorials
Reference
Articles
Forum
Tutorials Arrays
C++ Language An array is a series of elements of the same type placed in contiguous memory locations that can be individually
Ascii referenced by adding an index to a unique identifer.
Codes
Boolean Operations That means that, for example, fve values of type int can be declared as an array without having to declare 5 diferent
Numerical Bases variables (each with its own identifer). Instead, using an array, the fve int values are stored in contiguous memory
locations, and all fve can be accessed using the same identifer, with the proper index.
For example, an array containing 5 integer values of type int called foo could be represented as:
Introduction:
Compilers
Basics of C++:
Structure of a
program
Variables and types where each blank panel represents an element of the array. In this case, these are values of type int. These elements
Consants are numbered from 0 to 4, being 0 the frst and 4 the last; In C++, the frst element in an array is always numbered
Operators with a zero (not a one), no matter its length.
Basic Input/Output
Like a regular variable, an array must be declared before it is used. A typical declaration for an array in C++ is:
Program sructure:
Statements and fow type name [elements];
control
Functions where type is a valid type (such as int, foat...), name is a valid identifer and the elements feld (which is always
Overloads and enclosed in square brackets []), specifes the length of the array in terms of the number of elements.
templates
Therefore, the foo array, with fve elements of type int, can be declared as:
Name
visibility int foo [5];
Compound data types:
Arrays
Character sequences NOTE: The elements feld within square brackets [], representing the number of elements in the array, must be a
Pointers constant expression, since arrays are blocks of static memory whose size must be determined at compile time, before
Dynamic memory the program runs.
Data
sructures
Other data Initializing arrays
types By default, regular arrays of local scope (for example, those declared within a function) are left uninitialized. This
Classes: means that none of its elements are set to any particular value; their contents are undetermined at the point the array
is declared.
http://www.cplusplus.com/doc/tutorial/arrays/[03/12/2018 00:52:38]
Arrays - C++ Tutorials
Classes (I)
Classes (II)
But the elements in an array can be explicitly initialized to specifc values when it is declared, by enclosing those initial
Special members
values in braces {}. For example:
Type conversions
Exceptions This statement declares an array that can be represented like this:
Preprocessor directives
Standard library:
Input/output with
fles
The number of values between braces {} shall not be greater than the number of elements in the array. For example,
in the example above, foo was declared having 5 elements (as specifed by the number enclosed in square brackets,
[]), and the braces {} contained exactly 5 values, one for each element. If declared with less, the remaining elements
are set to their default values (which for fundamental types, means they are flled with zeroes). For example:
This creates an array of fve int values, each initialized with a value of zero:
When an initialization of values is provided for an array, C++ allows the possibility of leaving the square brackets
empty []. In this case, the compiler will assume automatically a size for the array that matches the number of values
included between the braces {}:
After this declaration, array foo would be 5 int long, since we have provided 5 initialization values.
Finally, the evolution of C++ has led to the adoption of universal initialization also for arrays. Therefore, there is no
longer need for the equal sign between the declaration and the initializer. Both these statements are equivalent:
http://www.cplusplus.com/doc/tutorial/arrays/[03/12/2018 00:52:38]
Arrays - C++ Tutorials
Static arrays, and those declared directly in a namespace (outside any function), are always initialized. If no explicit
initializer is specifed, all the elements are default-initialized (with zeroes, for fundamental types).
name[index]
Following the previous examples in which foo had 5 elements and each of those elements was of type int, the name
which can be used to refer to each element is the following:
For example, the following statement stores the value 75 in the third element of foo:
and, for example, the following copies the value of the third element of foo to a variable called x:
x =
foo[2];
Notice that the third element of foo is specifed foo[2], since the frst one is foo[0], the second one is foo[1], and
therefore, the third one is foo[2]. By this same reason, its last element is foo[4]. Therefore, if we write foo[5], we
would be accessing the sixth element of foo, and therefore actually exceeding the size of the array.
In C++, it is syntactically correct to exceed the valid range of indices for an array. This can create problems, since
accessing out-of-range elements do not cause errors on compilation, but can cause errors on runtime. The reason for
this being allowed will be seen in a later chapter when pointers are introduced.
At this point, it is important to be able to clearly distinguish between the two uses that brackets [] have related to
arrays. They perform two diferent tasks: one is to specify the size of arrays when they are declared; and the second
one is to specify indices for concrete array elements when they are accessed. Do not confuse these two possible uses
of brackets [] with arrays.
The main diference is that the declaration is preceded by the type of the elements, while the access is not.
1 foo[0] = a;
2 foo[a] = 75;
3 b = foo [a+2];
4 foo[foo[a]] = foo[2] + 5;
http://www.cplusplus.com/doc/tutorial/arrays/[03/12/2018 00:52:38]
Arrays - C++ Tutorials
For example:
Multidimensional arrays
Multidimensional arrays can be described as "arrays of arrays". For example, a bidimensional array can be imagined as
a two-dimensional table made of elements, all of them of a same uniform data type.
jimmy represents a bidimensional array of 3 per 5 elements of type int. The C++ syntax for this is:
int jimmy
[3][5];
and, for example, the way to reference the second element vertically and fourth horizontally in an expression would be:
jimmy[1][3]
Multidimensional arrays are not limited to two indices (i.e., two dimensions). They can contain as many indices as
needed. Although be careful: the amount of memory needed for an array increases exponentially with each dimension.
For example:
char century
http://www.cplusplus.com/doc/tutorial/arrays/[03/12/2018 00:52:38]
Arrays - C++ Tutorials
[100][365][24][60][60];
declares an array with an element of type char for each second in a century. This amounts to more than 3 billion char!
So this declaration would consume more than 3 gigabytes of memory!
At the end, multidimensional arrays are just an abstraction for programmers, since the same results can be achieved
with a simple array, by multiplying its indices:
With the only diference that with multidimensional arrays, the compiler automatically remembers the depth of each
imaginary dimension. The following two pieces of code produce the exact same result, but one uses a bidimensional
array while the other uses a simple array:
None of the two code snippets above produce any output on the screen, but both assign values to the memory block
called jimmy in the following way:
Note that the code uses defned constants for the width and height, instead of using directly their numerical values. This
gives the code a better readability, and allows changes in the code to be made easily in one place.
Arrays as parameters
At some point, we may need to pass an array to a function as a parameter. In C++, it is not possible to pass the entire
block of memory represented by an array to a function directly as an argument. But what can be passed instead is its
address. In practice, this has almost the same efect, and it is a much faster and more efcient operation.
To accept an array as parameter for a function, the parameters can be declared as the array type, but with empty
brackets, omitting the actual size of the array. For example:
http://www.cplusplus.com/doc/tutorial/arrays/[03/12/2018 00:52:38]
Arrays - C++ Tutorials
This function accepts a parameter of type "array of int" called arg. In order to pass to this function an array declared
as:
int myarray
[40];
procedure (myarray);
1 // arrays as parameters 5 10 15
2 #include <iosream> 2 4 6 8 10
3 using namespace sd;
4
5 void printarray (int arg[], int length) {
6 for (int n=0; n<length; ++n)
7 cout << arg[n] << ' ';
8 cout << '\n';
9 }
10
11 int main ()
12 {
13 int frsarray[] = {5, 10, 15};
14 int secondarray[] = {2, 4, 6, 8, 10};
15 printarray (frsarray,3);
16 printarray (secondarray,5);
17 }
In the code above, the frst parameter (int arg[]) accepts any array whose elements are of type int, whatever its
length. For that reason, we have included a second parameter that tells the function the length of each array that we
pass to it as its frst parameter. This allows the for loop that prints out the array to know the range to iterate in the
array passed, without going out of range.
In a function declaration, it is also possible to include multidimensional arrays. The format for a tridimensional array
parameter is:
base_type[][depth][depth]
Notice that the frst brackets [] are left empty, while the following ones specify sizes for their respective dimensions.
This is necessary in order for the compiler to be able to determine the depth of each additional dimension.
In a way, passing an array as argument always loses a dimension. The reason behind is that, for historical reasons,
arrays cannot be directly copied, and thus what is really passed is a pointer. This is a common source of errors for
novice programmers. Although a clear understanding of pointers, explained in a coming chapter, helps a lot.
Library arrays
The arrays explained above are directly implemented as a language feature, inherited from the C language. They are a
http://www.cplusplus.com/doc/tutorial/arrays/[03/12/2018 00:52:38]
Arrays - C++ Tutorials
great feature, but by restricting its copy and easily decay into pointers, they probably sufer from an excess of
optimization.
To overcome some of these issues with language built-in arrays, C++ provides an alternative array type as a standard
container. It is a type template (a class template, in fact) defned in header <array>.
Containers are a library feature that falls out of the scope of this tutorial, and thus the class will not be explained in
detail here. Sufce it to say that they operate in a similar way to built-in arrays, except that they allow being copied (an
actually expensive operation that copies the entire block of memory, and thus to use with care) and decay into pointers
only when explicitly told to do so (by means of its member data).
Just as an example, these are two versions of the same example using the language built-in array described in this
chapter, and the container in the library:
As you can see, both kinds of arrays use the same syntax to access its elements: myarray[i]. Other than that, the
main diferences lay on the declaration of the array, and the inclusion of an additional header for the library array.
Notice also how it is easy to access the size of the library array.
Previous: Next:
Name visibility Character sequences
Index
http://www.cplusplus.com/doc/tutorial/arrays/[03/12/2018 00:52:38]
Character sequences - C++ Tutorials
Go
C++
Information
Tutorials
Reference
Articles
Forum
http://www.cplusplus.com/doc/tutorial/ntcs/[03/12/2018 00:53:06]
Character sequences - C++ Tutorials
Classes (I)
array of characters with some predetermined sequence of characters, we can do it just like any other array:
Classes (II)
Special members char myword[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
Friendship and inheritance
Polymorphism
The above declares an array of 6 elements of type char initialized with the characters that form the word "Hello" plus
Type conversions a null character '\0' at the end.
Exceptions
Preprocessor directives But arrays of character elements have another way to be initialized: using string literals directly.
Standard library:
In the expressions used in some examples in previous chapters, string literals have already shown up several times.
Input/output with
These are specifed by enclosing the text between double quotes ("). For example:
fles
"the result is: "
Sequences of characters enclosed in double-quotes (") are literal constants. And their type is, in fact, a null-terminated
array of characters. This means that string literals always have a null character ( '\0') automatically appended at the
end.
Therefore, the array of char elements called myword can be initialized with a null-terminated sequence of characters by
either one of these two statements:
In both cases, the array of characters myword is declared with a size of 6 elements of type char: the 5 characters that
compose the word "Hello", plus a fnal null character ('\0'), which specifes the end of the sequence and that, in the
second case, when using double quotes (") it is appended automatically.
Please notice that here we are talking about initializing an array of characters at the moment it is being declared, and
not about assigning values to them later (once they have already been declared). In fact, because string literals are
regular arrays, they have the same restrictions as these, and cannot be assigned values.
Expressions (once myword has already been declared as above), such as:
1 myword = "Bye";
2 myword[] = "Bye";
This is because arrays cannot be assigned values. Note, though, that each of its elements can be assigned a value
individually. For example, this would be correct:
1 myword[0] = 'B';
2 myword[1] = 'y';
3 myword[2] = 'e';
4 myword[3] = '\0';
http://www.cplusplus.com/doc/tutorial/ntcs/[03/12/2018 00:53:06]
Character sequences - C++ Tutorials
In the standard library, both representations for strings (C-strings and library strings) coexist, and most functions
requiring strings are overloaded to support both.
For example, cin and cout support null-terminated sequences directly, allowing them to be directly extracted from cin
or inserted into cout, just like strings. For example:
In this example, both arrays of characters using null-terminated sequences and strings are used. They are quite
interchangeable in their use together with cin and cout, but there is a notable diference in their declarations: arrays
have a fxed size that needs to be specifed either implicit or explicitly when declared; quesion1 has a size of exactly 20
characters (including the terminating null-characters) and answer1 has a size of 80 characters; while strings are simply
strings, no size is specifed. This is due to the fact that strings have a dynamic size determined during runtime, while
the size of arrays is determined on compilation, before the program runs.
In any case, null-terminated character sequences and strings are easily transformed from one another:
Null-terminated character sequences can be transformed into strings implicitly, and strings can be transformed into
null-terminated character sequences by using either of sring's member functions c_sr or data:
Previous: Next:
Arrays Pointers
http://www.cplusplus.com/doc/tutorial/ntcs/[03/12/2018 00:53:06]
Character sequences - C++ Tutorials
Index
http://www.cplusplus.com/doc/tutorial/ntcs/[03/12/2018 00:53:06]
Pointers - C++ Tutorials
Go
C++
Information
Tutorials
Reference
Articles
Forum
Tutorials Pointers
C++ Language In earlier chapters, variables have been explained as locations in the computer's memory which can be accessed by
Ascii their identifer (their name). This way, the program does not need to care about the physical address of the data in
Codes memory; it simply uses the identifer whenever it needs to refer to the variable.
Boolean Operations
Numerical Bases For a C++ program, the memory of a computer is like a succession of memory cells, each one byte in size, and each
with a unique address. These single-byte memory cells are ordered in a way that allows data representations larger
C++ Language than one byte to occupy memory cells that have consecutive addresses.
Introduction:
This way, each cell can be easily located in the memory by means of its unique address. For example, the memory cell
Compilers with the address 1776 always follows immediately after the cell with address 1775 and precedes the one with 1777, and
Basics of C++: is exactly one thousand cells after 776 and exactly one thousand cells before 2776.
Structure of a
program When a variable is declared, the memory needed to store its value is assigned a specifc location in memory (its
Variables and types memory address). Generally, C++ programs do not actively decide the exact memory addresses where its variables are
Consants
stored. Fortunately, that task is left to the environment where the program is run - generally, an operating system that
decides the particular memory locations on runtime. However, it may be useful for a program to be able to obtain the
Operators
address of a variable during runtime in order to access data cells that are at a certain position relative to it.
Basic Input/Output
Program sructure:
Statements and fow Address-of operator (&)
control
The address of a variable can be obtained by preceding the name of a variable with an ampersand sign (&), known as
Functions address-of operator. For example:
Overloads and
templates foo =
Name &myvar;
visibility
Compound data types:
This would assign the address of variable myvar to foo; by preceding the name of the variable myvar with the address-
Arrays
of operator (&), we are no longer assigning the content of the variable itself to foo, but its address.
Character sequences
Pointers The actual address of a variable in memory cannot be known before runtime, but let's assume, in order to help clarify
Dynamic memory some concepts, that myvar is placed during runtime in the memory address 1776.
Data
sructures In this case, consider the following code fragment:
Other data
1 myvar = 25;
types 2 foo =
Classes: 3 &myvar;
bar = myvar;
http://www.cplusplus.com/doc/tutorial/pointers/[03/12/2018 00:53:28]
Pointers - C++ Tutorials
Classes (I)
Classes (II)
Special members The values contained in each variable after the execution of this are shown in the following diagram:
Friendship and inheritance
Polymorphism
Other language features:
Type conversions
Exceptions
Preprocessor directives
Standard library:
Input/output with
fles
First, we have assigned the value 25 to myvar (a variable whose address in memory we assumed to be 1776).
The second statement assigns foo the address of myvar, which we have assumed to be 1776.
Finally, the third statement, assigns the value contained in myvar to bar. This is a standard assignment operation, as
already done many times in earlier chapters.
The main diference between the second and third statements is the appearance of the address-of operator (&).
The variable that stores the address of another variable (like foo in the previous example) is what in C++ is called a
pointer. Pointers are a very powerful feature of the language that has many uses in lower level programming. A bit
later, we will see how to declare and use pointers.
An interesting property of pointers is that they can be used to access the variable they point to directly. This is done by
preceding the pointer name with the dereference operator (*). The operator itself can be read as "value pointed to by".
Therefore, following with the values of the previous example, the following statement:
baz = *foo;
This could be read as: "baz equal to value pointed to by foo", and the statement would actually assign the value 25 to
baz, since foo is 1776, and the value pointed to by 1776 (following the example above) would be 25.
http://www.cplusplus.com/doc/tutorial/pointers/[03/12/2018 00:53:28]
Pointers - C++ Tutorials
It is important to clearly diferentiate that foo refers to the value 1776, while *foo (with an asterisk * preceding the
identifer) refers to the value stored at address 1776, which in this case is 25. Notice the diference of including or not
including the dereference operator (I have added an explanatory comment of how each of these two expressions could
be read):
& is the address-of operator, and can be read simply as "address of"
* is the dereference operator, and can be read as "value pointed to by"
Thus, they have sort of opposite meanings: An address obtained with & can be dereferenced with *.
1 myvar = 25;
2 foo = &myvar;
Right after these two statements, all of the following expressions would give true as result:
1 myvar == 25
2 &myvar ==
3 1776
4 foo == 1776
*foo == 25
The frst expression is quite clear, considering that the assignment operation performed on myvar was myvar=25. The
second one uses the address-of operator (&), which returns the address of myvar, which we assumed it to have a value
of 1776. The third one is somewhat obvious, since the second expression was true and the assignment operation
performed on foo was foo=&myvar. The fourth expression uses the dereference operator (*) that can be read as "value
pointed to by", and the value pointed to by foo is indeed 25.
So, after all that, you may also infer that for as long as the address pointed to by foo remains unchanged, the
following expression will also be true:
*foo ==
myvar
http://www.cplusplus.com/doc/tutorial/pointers/[03/12/2018 00:53:28]
Pointers - C++ Tutorials
Declaring pointers
Due to the ability of a pointer to directly refer to the value that it points to, a pointer has diferent properties when it
points to a char than when it points to an int or a foat. Once dereferenced, the type needs to be known. And for that,
the declaration of a pointer needs to include the data type the pointer is going to point to.
type * name;
where type is the data type pointed to by the pointer. This type is not the type of the pointer itself, but the type of the
data the pointer points to. For example:
1 int * number;
2 char * character;
3 double * decimals;
These are three declarations of pointers. Each one is intended to point to a diferent data type, but, in fact, all of them
are pointers and all of them are likely going to occupy the same amount of space in memory (the size in memory of a
pointer depends on the platform where the program runs). Nevertheless, the data to which they point to do not occupy
the same amount of space nor are of the same type: the frst one points to an int, the second one to a char, and the
last one to a double. Therefore, although these three example variables are all of them pointers, they actually have
diferent types: int*, char*, and double* respectively, depending on the type they point to.
Note that the asterisk (*) used when declaring a pointer only means that it is a pointer (it is part of its type compound
specifer), and should not be confused with the dereference operator seen a bit earlier, but which is also written with an
asterisk (*). They are simply two diferent things represented with the same sign.
Notice that even though neither frsvalue nor secondvalue are directly set any value in the program, both end up with
a value set indirectly through the use of mypointer. This is how it happens:
First, mypointer is assigned the address of frstvalue using the address-of operator (&). Then, the value pointed to by
mypointer is assigned a value of 10. Because, at this moment, mypointer is pointing to the memory location of
frsvalue, this in fact modifes the value of frsvalue.
http://www.cplusplus.com/doc/tutorial/pointers/[03/12/2018 00:53:28]
Pointers - C++ Tutorials
In order to demonstrate that a pointer may point to diferent variables during its lifetime in a program, the example
repeats the process with secondvalue and that same pointer, mypointer.
Each assignment operation includes a comment on how each line could be read: i.e., replacing ampersands (&) by
"address of", and asterisks (*) by "value pointed to by".
Notice that there are expressions with pointers p1 and p2, both with and without the dereference operator (*). The
meaning of an expression using the dereference operator (*) is very diferent from one that does not. When this
operator precedes the pointer name, the expression refers to the value being pointed, while when a pointer name
appears without this operator, it refers to the value of the pointer itself (i.e., the address of what the pointer is pointing
to).
This declares the two pointers used in the previous example. But notice that there is an asterisk (*) for each pointer, in
order for both to have type int* (pointer to int). This is required due to the precedence rules. Note that if, instead, the
code was:
p1 would indeed be of type int*, but p2 would be of type int. Spaces do not matter at all for this purpose. But
anyway, simply remembering to put one asterisk per pointer is enough for most pointer users interested in declaring
multiple pointers per statement. Or even better: use a diferent statement for each variable.
http://www.cplusplus.com/doc/tutorial/pointers/[03/12/2018 00:53:28]
Pointers - C++ Tutorials
mypointer = myarray;
After that, mypointer and myarray would be equivalent and would have very similar properties. The main diference
being that mypointer can be assigned a diferent address, whereas myarray can never be assigned anything, and will
always represent the same block of 20 elements of type int. Therefore, the following assignment would not be valid:
myarray = mypointer;
Pointers and arrays support the same set of operations, with the same meaning for both. The main diference being
that pointers can be assigned new addresses, while arrays cannot.
In the chapter about arrays, brackets ([]) were explained as specifying the index of an element of the array. Well, in
fact these brackets are a dereferencing operator known as ofset operator. They dereference the variable they follow
just as * does, but they also add the number between brackets to the address being dereferenced. For example:
1 a[5] = 0; // a [ofset of 5] = 0
2 *(a+5) = 0; // pointed to by (a+5) = 0
These two expressions are equivalent and valid, not only if a is a pointer, but also if a is an array. Remember that if an
array, its name can be used just like a pointer to its frst element.
Pointer initialization
Pointers can be initialized to point to specifc locations at the very moment they are defned:
1 int myvar;
2 int * myptr =
http://www.cplusplus.com/doc/tutorial/pointers/[03/12/2018 00:53:28]
Pointers - C++ Tutorials
&myvar;
The resulting state of variables after this code is the same as after:
1 int myvar;
2 int * myptr;
3 myptr = &myvar;
When pointers are initialized, what is initialized is the address they point to (i.e., myptr), never the value being pointed
(i.e., *myptr). Therefore, the code above shall not be confused with:
1 int myvar;
2 int * myptr;
3 *myptr = &myvar;
Which anyway would not make much sense (and is not valid code).
The asterisk (*) in the pointer declaration (line 2) only indicates that it is a pointer, it is not the dereference operator
(as in line 3). Both things just happen to use the same sign: *. As always, spaces are not relevant, and never change
the meaning of an expression.
Pointers can be initialized either to the address of a variable (such as in the case above), or to the value of another
pointer (or array):
1 int myvar;
2 int *foo = &myvar;
3 int *bar = foo;
Pointer arithmetics
To conduct arithmetical operations on pointers is a little diferent than to conduct them on regular integer types. To
begin with, only addition and subtraction operations are allowed; the others make no sense in the world of pointers.
But both addition and subtraction have a slightly diferent behavior with pointers, according to the size of the data type
to which they point.
When fundamental data types were introduced, we saw that types have diferent sizes. For example: char always has a
size of 1 byte, short is generally larger than that, and int and long are even larger; the exact size of these being
dependent on the system. For example, let's imagine that in a given system, char takes 1 byte, short takes 2 bytes,
and long takes 4.
1 char *mychar;
2 short *myshort;
3 long *mylong;
and that we know that they point to the memory locations 1000, 2000, and 3000, respectively.
Therefore, if we write:
1 ++mychar;
2 ++myshort;
http://www.cplusplus.com/doc/tutorial/pointers/[03/12/2018 00:53:28]
Pointers - C++ Tutorials
3 ++mylong;
mychar, as one would expect, would contain the value 1001. But not so obviously, myshort would contain the value
2002, and mylong would contain 3004, even though they have each been incremented only once. The reason is that,
when adding one to a pointer, the pointer is made to point to the following element of the same type, and, therefore,
the size in bytes of the type it points to is added to the pointer.
This is applicable both when adding and subtracting any number to a pointer. It would happen exactly the same if we
wrote:
1 mychar = mychar + 1;
2 myshort = myshort +
3 1;
mylong = mylong + 1;
Regarding the increment (++) and decrement (--) operators, they both can be used as either prefx or sufx of an
expression, with a slight diference in behavior: as a prefx, the increment happens before the expression is evaluated,
and as a sufx, the increment happens after the expression is evaluated. This also applies to expressions incrementing
and decrementing pointers, which can become part of more complicated expressions that also include dereference
operators (*). Remembering operator precedence rules, we can recall that postfx operators, such as increment and
decrement, have higher precedence than prefx operators, such as the dereference operator (*). Therefore, the
following expression:
*p++
is equivalent to *(p++). And what it does is to increase the value of p (so it now points to the next element), but
because ++ is used as postfx, the whole expression is evaluated as the value pointed originally by the pointer (the
address it pointed to before being incremented).
Essentially, these are the four possible combinations of the dereference operator with both the prefx and sufx
versions of the increment operator (the same being applicable also to the decrement operator):
http://www.cplusplus.com/doc/tutorial/pointers/[03/12/2018 00:53:28]
Pointers - C++ Tutorials
*p++ = *q++;
Because ++ has a higher precedence than *, both p and q are incremented, but because both increment operators (++)
are used as postfx and not prefx, the value assigned to *p is *q before both p and q are incremented. And then both
are incremented. It would be roughly equivalent to:
1 *p = *q;
2 ++p;
3 ++q;
1 int x;
2 int y = 10;
3 cons int * p = &y;
4 x = *p; // ok: reading p
5 *p = x; // error: modifying p, which is cons-qualifed
Here p points to a variable, but points to it in a cons-qualifed manner, meaning that it can read the value pointed, but
it cannot modify it. Note also, that the expression &y is of type int*, but this is assigned to a pointer of type cons
int*. This is allowed: a pointer to non-const can be implicitly converted to a pointer to const. But not the other way
around! As a safety feature, pointers to cons are not implicitly convertible to pointers to non-cons.
One of the use cases of pointers to cons elements is as function parameters: a function that takes a pointer to
non-cons as parameter can modify the value passed as argument, while a function that takes a pointer tocons as
parameter cannot.
1 // pointers as arguments: 11
2 #include <iosream> 21
3 using namespace sd; 31
4
5 void increment_all (int* sart, int* sop)
6 {
7 int * current = sart;
8 while (current != sop) {
9 ++(*current); // increment value pointed
10 ++current; // increment pointer
11 }
12 }
13
14 void print_all (cons int* sart, cons int* sop)
15 {
16 cons int * current = sart;
17 while (current != sop) {
18 cout << *current << '\n';
19 ++current; // increment pointer
20 }
21 }
22
http://www.cplusplus.com/doc/tutorial/pointers/[03/12/2018 00:53:28]
Pointers - C++ Tutorials
23 int main ()
24 {
25 int numbers[] = {10,20,30};
26 increment_all (numbers,numbers+3);
27 print_all (numbers,numbers+3);
28 return 0;
29 }
Note that print_all uses pointers that point to constant elements. These pointers point to constant content they
cannot modify, but they are not constant themselves: i.e., the pointers can still be incremented or assigned diferent
addresses, although they cannot modify the content they point to.
And this is where a second dimension to constness is added to pointers: Pointers can also be themselves const. And
this is specifed by appending const to the pointed type (after the asterisk):
1 int x;
2 int * p1 = &x; // non-cons pointer to non-cons
3 int
4 cons int * p2 = &x; // non-cons pointer to cons int
5 int * cons p3 = &x; // cons pointer to non-cons int
cons int * cons p4 = &x; // cons pointer to cons int
The syntax with cons and pointers is defnitely tricky, and recognizing the cases that best suit each use tends to require
some experience. In any case, it is important to get constness with pointers (and references) right sooner rather than
later, but you should not worry too much about grasping everything if this is the frst time you are exposed to the mix
of cons and pointers. More use cases will show up in coming chapters.
To add a little bit more confusion to the syntax of cons with pointers, the cons qualifer can either precede or follow the
pointed type, with the exact same meaning:
As with the spaces surrounding the asterisk, the order of const in this case is simply a matter of style. This chapter
uses a prefx cons, as for historical reasons this seems to be more extended, but both are exactly equivalent. The
merits of each style are still intensely debated on the internet.
But they can also be accessed directly. String literals are arrays of the proper array type to contain all its characters
plus the terminating null-character, with each of the elements being of type cons char (as literals, they can never be
modifed). For example:
This declares an array with the literal representation for "hello", and then a pointer to its frst element is assigned to
foo. If we imagine that "hello" is stored at the memory locations that start at address 1702, we can represent the
previous declaration as:
http://www.cplusplus.com/doc/tutorial/pointers/[03/12/2018 00:53:28]
Pointers - C++ Tutorials
Note that here foo is a pointer and contains the value 1702, and not 'h', nor "hello", although 1702 indeed is the
address of both of these.
The pointer foo points to a sequence of characters. And because pointers and arrays behave essentially in the same
way in expressions, foo can be used to access the characters in the same way arrays of null-terminated character
sequences are. For example:
1 *(foo+4)
2 foo[4]
Both expressions have a value of 'o' (the ffth element of the array).
Pointers to pointers
C++ allows the use of pointers that point to pointers, that these, in its turn, point to data (or even to other pointers).
The syntax simply requires an asterisk (*) for each level of indirection in the declaration of the pointer:
1 char a;
2 char * b;
3 char **
4 c;
5 a = 'z';
6 b = &a;
c = &b;
This, assuming the randomly chosen memory locations for each variable of 7230, 8092, and 10502, could be
represented as:
With the value of each variable represented inside its corresponding cell, and their respective addresses in memory
represented by the value under them.
The new thing in this example is variable c, which is a pointer to a pointer, and can be used in three diferent levels of
indirection, each one of them would correspond to a diferent value:
http://www.cplusplus.com/doc/tutorial/pointers/[03/12/2018 00:53:28]
Pointers - C++ Tutorials
void pointers
The void type of pointer is a special type of pointer. In C++, void represents the absence of type. Therefore, void
pointers are pointers that point to a value that has no type (and thus also an undetermined length and undetermined
dereferencing properties).
This gives void pointers a great fexibility, by being able to point to any data type, from an integer value or a foat to a
string of characters. In exchange, they have a great limitation: the data pointed to by them cannot be directly
dereferenced (which is logical, since we have no type to dereference to), and for that reason, any address in a void
pointer needs to be transformed into some other pointer type that points to a concrete data type before being
dereferenced.
One of its possible uses may be to pass generic parameters to a function. For example:
1 // increaser y, 1603
2 #include <iosream>
3 using namespace sd;
4
5 void increase (void* data, int psize)
6 {
7 if ( psize == sizeof(char) )
8 { char* pchar; pchar=(char*)data; ++(*pchar);
9 }
10 else if (psize == sizeof(int) )
11 { int* pint; pint=(int*)data; ++(*pint); }
12 }
13
14 int main ()
15 {
16 char a = 'x';
17 int b = 1602;
18 increase (&a,sizeof(a));
19 increase (&b,sizeof(b));
20 cout << a << ", " << b << '\n';
21 return 0;
}
sizeof is an operator integrated in the C++ language that returns the size in bytes of its argument. For non-dynamic
data types, this value is a constant. Therefore, for example, sizeof(char) is 1, because char has always a size of one
byte.
Neither p nor q point to addresses known to contain a value, but none of the above statements causes an error. In
C++, pointers are allowed to take any address value, no matter whether there actually is something at that address or
not. What can cause an error is to dereference such a pointer (i.e., actually accessing the value they point to).
Accessing such a pointer causes undefned behavior, ranging from an error during runtime to accessing some random
value.
http://www.cplusplus.com/doc/tutorial/pointers/[03/12/2018 00:53:28]
Pointers - C++ Tutorials
But, sometimes, a pointer really needs to explicitly point to nowhere, and not just an invalid address. For such cases,
there exists a special value that any pointer type can take: the null pointer value. This value can be expressed in C++
in two ways: either with an integer value of zero, or with the nullptr keyword:
1 int * p = 0;
2 int * q = nullptr;
Here, both p and q are null pointers, meaning that they explicitly point to nowhere, and they both actually compare
equal: all null pointers compare equal to other null pointers. It is also quite usual to see the defned constant NULL be
used in older code to refer to the null pointer value:
int * r = NULL;
NULL is defned in several headers of the standard library, and is defned as an alias of some null pointer constant value
(such as 0 or nullptr).
Do not confuse null pointers with void pointers! A null pointer is a value that any pointer can take to represent that it is
pointing to "nowhere", while a void pointer is a type of pointer that can point to somewhere without a specifc type.
One refers to the value stored in the pointer, and the other to the type of data it points to.
Pointers to functions
C++ allows operations with pointers to functions. The typical use of this is for passing a function as an argument to
another function. Pointers to functions are declared with the same syntax as a regular function declaration, except that
the name of the function is enclosed between parentheses () and an asterisk (*) is inserted before the name:
1 // pointer to functions 8
2 #include <iosream>
3 using namespace sd;
4
5 int addition (int a, int b)
6 { return (a+b); }
7
8 int subtraction (int a, int b)
9 { return (a-b); }
10
11 int operation (int x, int y, int
12 (*functocall)(int,int))
13 {
14 int g;
15 g = (*functocall)(x,y);
16 return (g);
17 }
18
19 int main ()
20 {
21 int m,n;
22 int (*minus)(int,int) = subtraction;
23
24 m = operation (7, 5, addition);
25 n = operation (20, m, minus);
26 cout <<n;
27 return 0;
}
In the example above, minus is a pointer to a function that has two parameters of type int. It is directly initialized to
point to the function subtraction:
int (* minus)(int,int) =
subtraction;
http://www.cplusplus.com/doc/tutorial/pointers/[03/12/2018 00:53:28]
Pointers - C++ Tutorials
Previous: Next:
Character sequences Dynamic memory
Index
http://www.cplusplus.com/doc/tutorial/pointers/[03/12/2018 00:53:28]
Dynamic memory - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
http://www.cplusplus.com/doc/tutorial/dynamic/[03/12/2018 00:53:52]
Dynamic memory - C++ Tutorials
Classes (I)
Classes (II) memory using new. The most important diference is that the size of a regular array needs to be a constant expression,
and thus its size has to be determined at the moment of designing the program, before it is run, whereas the dynamic
Special members
memory allocation performed by new allows to assign memory during runtime using any variable value as size.
Friendship and inheritance
Polymorphism The dynamic memory requested by our program is allocated by the system from the memory heap. However, computer
Other language features: memory is a limited resource, and it can be exhausted. Therefore, there are no guarantees that all requests to allocate
Type conversions memory using operator new are going to be granted by the system.
Exceptions
Preprocessor directives C++ provides two standard mechanisms to check if the allocation was successful:
Standard library:
One is by handling exceptions. Using this method, an exception of type bad_alloc is thrown when the allocation fails.
Input/output with Exceptions are a powerful C++ feature explained later in these tutorials. But for now, you should know that if this
fles exception is thrown and it is not handled by a specifc handler, the program execution is terminated.
This exception method is the method used by default by new, and is the one used in a declaration like:
The other method is known as nothrow, and what happens when it is used is that when a memory allocation fails,
instead of throwing a bad_alloc exception or terminating the program, the pointer returned by new is a null pointer,
and the program continues its execution normally.
This method can be specifed by using a special object called nothrow, declared in header <new>, as argument for new:
In this case, if the allocation of this block of memory fails, the failure can be detected by checking if foo is a null
pointer:
1 int * foo;
2 foo = new (nothrow) int [5];
3 if (foo == nullptr) {
4 // error assigning memory. Take
5 measures.
}
This nothrow method is likely to produce less efcient code than exceptions, since it implies explicitly checking the
pointer value returned after each and every allocation. Therefore, the exception mechanism is generally preferred, at
least for critical allocations. Still, most of the coming examples will use the nothrow mechanism due to its simplicity.
1 delete pointer;
2 delete[] pointer;
The frst statement releases the memory of a single element allocated using new, and the second one releases the
memory allocated for arrays of elements using new and a size in brackets ([]).
http://www.cplusplus.com/doc/tutorial/dynamic/[03/12/2018 00:53:52]
Dynamic memory - C++ Tutorials
The value passed as argument to delete shall be either a pointer to a memory block previously allocated with new, or a
null pointer (in the case of a null pointer, delete produces no efect).
Notice how the value within brackets in the new statement is a variable value entered by the user ( i), not a constant
expression:
There always exists the possibility that the user introduces a value for i so big that the system cannot allocate enough
memory for it. For example, when I tried to give a value of 1 billion to the "How many numbers" question, my system
could not allocate that much memory for the program, and I got the text message we prepared for this case (Error:
memory could not be allocated).
It is considered good practice for programs to always be able to handle failures to allocate memory, either by checking
the pointer value (if nothrow) or by catching the proper exception.
Dynamic memory in C
C++ integrates the operators new and delete for allocating dynamic memory. But these were not available in the C
language; instead, it used a library solution, with the functions malloc, calloc, realloc and free, defned in the
header <csdlib> (known as <sdlib.h> in C). The functions are also available in C++ and can also be used to allocate
and deallocate dynamic memory.
Note, though, that the memory blocks allocated by these functions are not necessarily compatible with those returned
by new, so they should not be mixed; each one should be handled with its own set of functions or operators.
Previous: Next:
http://www.cplusplus.com/doc/tutorial/dynamic/[03/12/2018 00:53:52]
Dynamic memory - C++ Tutorials
http://www.cplusplus.com/doc/tutorial/dynamic/[03/12/2018 00:53:52]
Data structures - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
http://www.cplusplus.com/doc/tutorial/structures/[03/12/2018 00:54:15]
Data structures - C++ Tutorials
1 apple.weight
2 apple.price
3 banana.weight
4 banana.price
5 melon.weight
6 melon.price
Each one of these has the data type corresponding to the member they refer to: apple.weight, banana.weight, and
melon.weight are of type int, while apple.price, banana.price, and melon.price are of type double.
http://www.cplusplus.com/doc/tutorial/structures/[03/12/2018 00:54:15]
Data structures - C++ Tutorials
The example shows how the members of an object act just as regular variables. For example, the member yours.year
is a valid variable of type int, and mine.title is a valid variable of type sring.
But the objects mine and yours are also variables with a type (of type movies_t). For example, both have been passed
to function printmovie just as if they were simple variables. Therefore, one of the features of data structures is the
ability to refer to both their members individually or to the entire structure as a whole. In both cases using the same
identifer: the name of the structure.
Because structures are types, they can also be used as the type of arrays to construct tables or databases of them:
Pointers to structures
Like any other type, structures can be pointed to by its own type of pointers:
1 sruct movies_t {
2 sring title;
3 int year;
4 };
5
6 movies_t amovie;
7 movies_t * pmovie;
Here amovie is an object of structure type movies_t, and pmovie is a pointer to point to objects of structure type
movies_t. Therefore, the following code would also be valid:
http://www.cplusplus.com/doc/tutorial/structures/[03/12/2018 00:54:15]
Data structures - C++ Tutorials
pmovie = &amovie;
The value of the pointer pmovie would be assigned the address of object amovie.
Now, let's see another example that mixes pointers and structures, and will serve to introduce a new operator: the
arrow operator (->):
The arrow operator (->) is a dereference operator that is used exclusively with pointers to objects that have members.
This operator serves to access the member of an object directly from its address. For example, in the example above:
pmovie->title
(*pmovie).title
Both expressions, pmovie->title and (*pmovie).title are valid, and both access the member title of the data
structure pointed by a pointer called pmovie. It is defnitely something diferent than:
*pmovie.title
*(pmovie.title)
http://www.cplusplus.com/doc/tutorial/structures/[03/12/2018 00:54:15]
Data structures - C++ Tutorials
This would access the value pointed by a hypothetical pointer member called title of the structure object pmovie
(which is not the case, since title is not a pointer type). The following panel summarizes possible combinations of the
operators for pointers and for structure members:
Nesting structures
Structures can also be nested in such a way that an element of a structure is itself another structure:
1 sruct movies_t {
2 sring title;
3 int year;
4 };
5
6 sruct friends_t {
7 sring name;
8 sring email;
9 movies_t favorite_movie;
10 } charlie, maria;
11
12 friends_t * pfriends = &charlie;
After the previous declarations, all of the following expressions would be valid:
1 charlie.name
2 maria.favorite_movie.title
3 charlie.favorite_movie.year
4 pfriends->favorite_movie.year
(where, by the way, the last two expressions refer to the same member).
Previous: Next:
Dynamic memory Other data types
Index
http://www.cplusplus.com/doc/tutorial/structures/[03/12/2018 00:54:15]
Other data types - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
Unions
Unions allow one portion of memory to be accessed as diferent data types. Its declaration and use is similar to the one
of structures, but its functionality is totally diferent:
union type_name {
member_type1
member_name1;
member_type2
member_name2;
member_type3
member_name3;
.
.
} object_names;
This creates a new union type, identifed by type_name, in which all its member elements occupy the same physical
space in memory. The size of this type is the one of the largest member element. For example:
1 union mytypes_t {
2 char c;
3 int i;
4 foat f;
5 } mytypes;
1 mytypes.c
2 mytypes.i
3 mytypes.f
Each of these members is of a diferent data type. But since all of them are referring to the same location in memory,
http://www.cplusplus.com/doc/tutorial/other_data_types/[03/12/2018 00:54:37]
Other data types - C++ Tutorials
the modifcation of one of the members will afect the value of all of them. It is not possible to store diferent values in
them in a way that each is independent of the others.
One of the uses of a union is to be able to access a value either in its entirety or as an array or structure of smaller
elements. For example:
1 union mix_t {
2 int l;
3 sruct {
4 short hi;
5 short lo;
6 } s;
7 char c[4];
8 } mix;
If we assume that the system where this program runs has an int type with a size of 4 bytes, and a short type of 2
bytes, the union defned above allows the access to the same group of 4 bytes: mix.l, mix.s and mix.c, and which we
can use according to how we want to access these bytes: as if they were a single value of type int, or as if they were
two values of type short, or as an array of char elements, respectively. The example mixes types, arrays, and
structures in the union to demonstrate diferent ways to access the data. For a little-endian system, this union could be
represented as:
The exact alignment and order of the members of a union in memory depends on the system, with the possibility of
creating portability issues.
Anonymous unions
When unions are members of a class (or structure), they can be declared with no name. In this case, they become
anonymous unions, and its members are directly accessible from objects by their member names. For example, see the
diferences between these two structure declarations:
The only diference between the two types is that in the frst one, the member union has a name (price), while in the
second it has not. This afects the way to access members dollars and yen of an object of this type. For an object of
the frst type (with a regular union), it would be:
1 book1.price.dollars
2 book1.price.yen
whereas for an object of the second type (which has an anonymous union), it would be:
1 book2.dollars
2 book2.yen
Again, remember that because it is a member union (not a member structure), the members dollars and yen actually
share the same memory location, so they cannot be used to store two diferent values simultaneously. The price can
be set in dollars or in yen, but not in both simultaneously.
enum type_name {
value1,
value2,
value3,
.
.
} object_names;
This creates the type type_name, which can take any of value1, value2, value3, ... as value. Objects (variables) of this
type can directly be instantiated as object_names.
For example, a new type of variable called colors_t could be defned to store colors with the following declaration:
Notice that this declaration includes no other type, neither fundamental nor compound, in its defnition. To say it
another way, somehow, this creates a whole new data type from scratch without basing it on any other existing type.
The possible values that variables of this new type color_t may take are the enumerators listed within braces. For
example, once the colors_t enumerated type is declared, the following expressions will be valid:
1 colors_t mycolor;
2
3 mycolor = blue;
4 if (mycolor == green) mycolor = red;
Values of enumerated types declared with enum are implicitly convertible to an integer type, and vice versa. In fact, the
elements of such an enum are always assigned an integer numerical equivalent internally, to which they can be
implicitly converted to or from. If it is not specifed otherwise, the integer value equivalent to the frst possible value is
0, the equivalent to the second is 1, to the third is 2, and so on... Therefore, in the data type colors_t defned above,
black would be equivalent to 0, blue would be equivalent to 1, green to 2, and so on...
http://www.cplusplus.com/doc/tutorial/other_data_types/[03/12/2018 00:54:37]
Other data types - C++ Tutorials
A specifc integer value can be specifed for any of the possible values in the enumerated type. And if the constant
value that follows it is itself not given its own value, it is automatically assumed to be the same value plus one. For
example:
In this case, the variable y2k of the enumerated type months_t can contain any of the 12 possible values that go from
january to december and that are equivalent to the values between 1 and 12 (not between 0 and 11, since january has
been made equal to 1).
The implicit conversion works both ways: a value of type months_t can be assigned a value of 1 (which would be
equivalent to january), or an integer variable can be assigned a value of january (equivalent to 1).
enum class Colors {black, blue, green, cyan, red, purple, yellow,
white};
Each of the enumerator values of an enum class type needs to be scoped into its type (this is actually also possible
with enum types, but it is only optional). For example:
1 Colors mycolor;
2
3 mycolor = Colors::blue;
4 if (mycolor == Colors::green) mycolor = Colors::red;
Enumerated types declared with enum class also have more control over their underlying type; it may be any integral
data type, such as char, short or unsigned int, which essentially serves to determine the size of the type. This is
specifed by a colon and the underlying type following the enumerated type. For example:
Here, Eyecolor is a distinct type with the same size of a char (1 byte).
Previous: Next:
Data structures Classes (I)
Index
http://www.cplusplus.com/doc/tutorial/other_data_types/[03/12/2018 00:54:37]
Classes (I) - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
C++ Language Classes are defned using either keyword class or keyword sruct, with the following syntax:
Introduction:
class class_name {
Compilers access_specifer_1:
Basics of C++: member1;
access_specifer_2:
Structure of a member2;
...
program } object_names;
Variables and types
Consants Where class_name is a valid identifer for the class, object_names is an optional list of names for objects of this class.
Operators The body of the declaration can contain members, which can either be data or function declarations, and optionally
Basic Input/Output access specifers.
Program sructure:
Classes have the same format as plain data structures, except that they can also include functions and have these new
Statements and fow
things called access specifers. An access specifer is one of the following three keywords: private, public or
control
protected. These specifers modify the access rights for the members that follow them:
Functions
Overloads and
templates private members of a class are accessible only from within other members of the same class (or from their
Name "friends").
protected members are accessible from other members of the same class (or from their"friends"), but also
visibility
from members of their derived classes.
Compound data types:
Finally, public members are accessible from anywhere where the object is visible.
Arrays
Character sequences
Pointers By default, all members of a class declared with the class keyword have private access for all its members. Therefore,
Dynamic memory any member that is declared before any other access specifer has private access automatically. For example:
Data
1 class Rectangle {
sructures 2 int width, height;
Other data 3 public:
4 void set_values (int,int);
types 5 int area (void);
6 } rect;
Classes:
http://www.cplusplus.com/doc/tutorial/classes/[03/12/2018 00:55:01]
Classes (I) - C++ Tutorials
Classes (I)
Classes (II)
Declares a class (i.e., a type) called Rectangle and an object (i.e., a variable) of this class, called rect. This class
Special members
contains four members: two data members of type int (member width and member height) with private access
Friendship and inheritance (because private is the default access level) and two member functions with public access: the functions set_values
Polymorphism and area, of which for now we have only included their declaration, but not their defnition.
Other language features:
Type conversions Notice the diference between the class name and the object name: In the previous example, Rectangle was the class
Exceptions name (i.e., the type), whereas rect was an object of type Rectangle. It is the same relationship int and a have in the
Preprocessor directives
following declaration:
Standard library:
int
Input/output with a;
fles
where int is the type name (the class) and a is the variable name (the object).
After the declarations of Rectangle and rect, any of the public members of object rect can be accessed as if they
were normal functions or normal variables, by simply inserting a dot (.) between object name and member name. This
follows the same syntax as accessing the members of plain data structures. For example:
1 rect.set_values (3,4);
2 myarea = rect.area();
The only members of rect that cannot be accessed from outside the class are width and height, since they have
private access and they can only be referred to from within other members of that same class.
This example reintroduces the scope operator (::, two colons), seen in earlier chapters in relation to namespaces. Here
it is used in the defnition of function set_values to defne a member of a class outside the class itself.
Notice that the defnition of the member function area has been included directly within the defnition of class
Rectangle given its extreme simplicity. Conversely, set_values it is merely declared with its prototype within the
class, but its defnition is outside it. In this outside defnition, the operator of scope (::) is used to specify that the
function being defned is a member of the class Rectangle and not a regular non-member function.
The scope operator (::) specifes the class to which the member being defned belongs, granting exactly the same
http://www.cplusplus.com/doc/tutorial/classes/[03/12/2018 00:55:01]
Classes (I) - C++ Tutorials
scope properties as if this function defnition was directly included within the class defnition. For example, the function
set_values in the previous example has access to the variables width and height, which are private members of class
Rectangle, and thus only accessible from other members of the class, such as this.
The only diference between defning a member function completely within the class defnition or to just include its
declaration in the function and defne it later outside the class, is that in the frst case the function is automatically
considered an inline member function by the compiler, while in the second it is a normal (not-inline) class member
function. This causes no diferences in behavior, but only on possible compiler optimizations.
Members width and height have private access (remember that if nothing else is specifed, all members of a class
defned with keyword class have private access). By declaring them private, access from outside the class is not
allowed. This makes sense, since we have already defned a member function to set values for those members within
the object: the member function set_values. Therefore, the rest of the program does not need to have direct access to
them. Perhaps in a so simple example as this, it is difcult to see how restricting access to these variables may be
useful, but in greater projects it may be very important that values cannot be modifed in an unexpected way
(unexpected from the point of view of the object).
The most important property of a class is that it is a type, and as such, we can declare multiple objects of it. For
example, following with the previous example of class Rectangle, we could have declared the object rectb in addition
to object rect:
In this particular case, the class (type of the objects) is Rectangle, of which there are two instances (i.e., objects):
rect and rectb. Each one of them has its own member variables and member functions.
Notice that the call to rect.area() does not give the same result as the call torectb.area(). This is because each
object of class Rectangle has its own variables width and height, as they -in some way- have also their own function
members set_value and area that operate on the object's own member variables.
Classes allow programming using object-oriented paradigms: Data and functions are both members of the object,
reducing the need to pass and carry handlers or other state variables as arguments to functions, because they are part
of the object whose member is called. Notice that no arguments were passed on the calls to rect.area or rectb.area.
Those member functions directly used the data members of their respective objects rect and rectb.
Constructors
http://www.cplusplus.com/doc/tutorial/classes/[03/12/2018 00:55:01]
Classes (I) - C++ Tutorials
What would happen in the previous example if we called the member function area before having called set_values?
An undetermined result, since the members width and height had never been assigned a value.
In order to avoid that, a class can include a special function called its constructor, which is automatically called
whenever a new object of this class is created, allowing the class to initialize member variables or allocate storage.
This constructor function is declared just like a regular member function, but with a name that matches the class name
and without any return type; not even void.
The results of this example are identical to those of the previous example. But now, class Rectangle has no member
function set_values, and has instead a constructor that performs a similar action: it initializes the values ofwidth and
height with the arguments passed to it.
Notice how these arguments are passed to the constructor at the moment at which the objects of this class are
created:
Constructors cannot be called explicitly as if they were regular member functions. They are only executed once, when a
new object of that class is created.
Notice how neither the constructor prototype declaration (within the class) nor the latter constructor defnition, have
return values; not even void: Constructors never return values, they simply initialize the object.
Overloading constructors
Like any other function, a constructor can also be overloaded with diferent versions taking diferent parameters: with a
diferent number of parameters and/or parameters of diferent types. The compiler will automatically call the one whose
parameters match the arguments:
http://www.cplusplus.com/doc/tutorial/classes/[03/12/2018 00:55:01]
Classes (I) - C++ Tutorials
In the above example, two objects of class Rectangle are constructed: rect and rectb. rect is constructed with two
arguments, like in the example before.
But this example also introduces a special kind constructor: the default constructor. The default constructor is the
constructor that takes no parameters, and it is special because it is called when an object is declared but is not
initialized with any arguments. In the example above, the default constructor is called for rectb. Note how rectb is not
even constructed with an empty set of parentheses - in fact, empty parentheses cannot be used to call the default
constructor:
This is because the empty set of parentheses would make of rectc a function declaration instead of an object
declaration: It would be a function that takes no arguments and returns a value of type Rectangle.
Uniform initialization
The way of calling constructors by enclosing their arguments in parentheses, as shown above, is known as functional
form. But constructors can also be called with other syntaxes:
First, constructors with a single parameter can be called using the variable initialization syntax (an equal sign followed
by the argument):
More recently, C++ introduced the possibility of constructors to be called using uniform initialization, which essentially
is the same as the functional form, but using braces ({}) instead of parentheses (()):
Optionally, this last syntax can include an equal sign before the braces.
http://www.cplusplus.com/doc/tutorial/classes/[03/12/2018 00:55:01]
Classes (I) - C++ Tutorials
Here is an example with four ways to construct objects of a class whose constructor takes a single parameter:
An advantage of uniform initialization over functional form is that, unlike parentheses, braces cannot be confused with
function declarations, and thus can be used to explicitly call default constructors:
The choice of syntax to call constructors is largely a matter of style. Most existing code currently uses functional form,
and some newer style guides suggest to choose uniform initialization over the others, even though it also has its
potential pitfalls for its preference of initializer_lis as its type.
1 class Rectangle {
2 int width,height;
3 public:
4 Rectangle(int,int);
5 int area() {return width*height;}
6 };
http://www.cplusplus.com/doc/tutorial/classes/[03/12/2018 00:55:01]
Classes (I) - C++ Tutorials
Or even:
Note how in this last case, the constructor does nothing else than initialize its members, hence it has an empty function
body.
For members of fundamental types, it makes no diference which of the ways above the constructor is defned, because
they are not initialized by default, but for member objects (those whose type is a class), if they are not initialized after
the colon, they are default-constructed.
Default-constructing all members of a class may or may always not be convenient: in some cases, this is a waste (when
the member is then reinitialized otherwise in the constructor), but in some other cases, default-construction is not even
possible (when the class does not have a default constructor). In these cases, members shall be initialized in the
member initialization list. For example:
In this example, class Cylinder has a member object whose type is another class (base's type is Circle). Because
objects of class Circle can only be constructed with a parameter, Cylinder's constructor needs to call base's
constructor, and the only way to do this is in the member initializer list.
These initializations can also use uniform initializer syntax, using braces {} instead of parentheses ():
Pointers to classes
http://www.cplusplus.com/doc/tutorial/classes/[03/12/2018 00:55:01]
Classes (I) - C++ Tutorials
Objects can also be pointed to by pointers: Once declared, a class becomes a valid type, so it can be used as the type
pointed to by a pointer. For example:
Rectangle * prect;
Similarly as with plain data structures, the members of an object can be accessed directly from a pointer by using the
arrow operator (->). Here is an example with some possible combinations:
This example makes use of several operators to operate on objects and pointers (operators *, &, ., ->, []). They can be
interpreted as:
Most of these expressions have been introduced in earlier chapters. Most notably, the chapter about arrays introduced
the ofset operator ([]) and the chapter about plain data structures introduced the arrow operator (->).
http://www.cplusplus.com/doc/tutorial/classes/[03/12/2018 00:55:01]
Classes (I) - C++ Tutorials
The keyword sruct, generally used to declare plain data structures, can also be used to declare classes that have
member functions, with the same syntax as with keyword class. The only diference between both is that members of
classes declared with the keyword sruct have public access by default, while members of classes declared with the
keyword class have private access by default. For all other purposes both keywords are equivalent in this context.
Conversely, the concept of unions is diferent from that of classes declared with sruct and class, since unions only
store one data member at a time, but nevertheless they are also classes and can thus also hold member functions. The
default access in union classes is public.
Previous: Next:
Other data types Classes (II)
Index
http://www.cplusplus.com/doc/tutorial/classes/[03/12/2018 00:55:01]
Classes (II) - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
http://www.cplusplus.com/doc/tutorial/templates/[03/12/2018 00:55:23]
Classes (II) - C++ Tutorials
Classes (I) cartesian vectors (3,1) and (1,2) together would result in (3+1,1+2) = (4,3). This could be implemented in C++
Classes (II) with the following code:
Special members
Friendship and inheritance 1 // overloading operators example 4,3
2 #include <iosream>
Polymorphism 3 using namespace sd;
4
Other language features: 5 class CVector {
Type conversions 6 public:
7 int x,y;
Exceptions 8 CVector () {};
Preprocessor directives 9 CVector (int a,int b) : x(a), y(b) {}
10 CVector operator + (cons CVector&);
Standard library: 11 };
12
Input/output with 13 CVector CVector::operator+ (cons CVector& param)
fles 14 {
15 CVector temp;
16 temp.x = x + param.x;
17 temp.y = y + param.y;
18 return temp;
19 }
20
21 int main () {
22 CVector foo (3,1);
23 CVector bar (1,2);
24 CVector result;
25 result = foo + bar;
26 cout << result.x << ',' << result.y << '\n';
27 return 0;
}
If confused about so many appearances of CVector, consider that some of them refer to the class name (i.e., the type)
CVector and some others are functions with that name (i.e., constructors, which must have the same name as the
class). For example:
The function operator+ of class CVector overloads the addition operator (+) for that type. Once declared, this function
can be called either implicitly using the operator, or explicitly using its functional name:
1 c = a + b;
2 c = a.operator+ (b);
The operator overloads are just regular functions which can have any behavior; there is actually no requirement that
the operation performed by that overload bears a relation to the mathematical or usual meaning of the operator,
although it is strongly recommended. For example, a class that overloads operator+ to actually subtract or that
overloads operator== to fll the object with zeros, is perfectly valid, although using such a class could be challenging.
The parameter expected for a member function overload for operations such as operator+ is naturally the operand to
the right hand side of the operator. This is common to all binary operators (those with an operand to its left and one
operand to its right). But operators can come in diverse forms. Here you have a table with a summary of the
parameters needed for each of the diferent operators than can be overloaded (please, replace @ by the operator in
each case):
http://www.cplusplus.com/doc/tutorial/templates/[03/12/2018 00:55:23]
Classes (II) - C++ Tutorials
Notice that some operators may be overloaded in two forms: either as a member function or as a non-member
function: The frst case has been used in the example above for operator+. But some operators can also be overloaded
as non-member functions; In this case, the operator function takes an object of the proper class as frst argument.
For example:
1 // non-member operator overloads 4,3
2 #include <iosream>
3 using namespace sd;
4
5 class CVector {
6 public:
7 int x,y;
8 CVector () {}
9 CVector (int a, int b) : x(a), y(b) {}
10 };
11
12
13 CVector operator+ (cons CVector& lhs, cons
14 CVector& rhs) {
15 CVector temp;
16 temp.x = lhs.x + rhs.x;
17 temp.y = lhs.y + rhs.y;
18 return temp;
19 }
20
21 int main () {
22 CVector foo (3,1);
23 CVector bar (1,2);
24 CVector result;
25 result = foo + bar;
26 cout << result.x << ',' << result.y << '\n';
27 return 0;
}
One of its uses can be to check if a parameter passed to a member function is the object itself. For example:
http://www.cplusplus.com/doc/tutorial/templates/[03/12/2018 00:55:23]
Classes (II) - C++ Tutorials
It is also frequently used in operator= member functions that return objects by reference. Following with the examples
on cartesian vector seen before, its operator= function could have been defned as:
In fact, this function is very similar to the code that the compiler generates implicitly for this class for operator=.
Static members
A class can contain static members, either data or functions.
A static data member of a class is also known as a "class variable", because there is only one common variable for all
the objects of that same class, sharing the same value: i.e., its value is not diferent from one object of this class to
another.
For example, it may be used for a variable within a class that can contain a counter with the number of objects of that
class that are currently allocated, as in the following example:
In fact, static members have the same properties as non-member variables but they enjoy class scope. For that reason,
and to avoid them to be declared several times, they cannot be initialized directly in the class, but need to be initialized
somewhere outside it. As in the previous example:
int Dummy::n=0;
http://www.cplusplus.com/doc/tutorial/templates/[03/12/2018 00:55:23]
Classes (II) - C++ Tutorials
Because it is a common variable value for all the objects of the same class, it can be referred to as a member of any
object of that class or even directly by the class name (of course this is only valid for static members):
These two calls above are referring to the same variable: the static variable n within class Dummy shared by all objects
of this class.
Again, it is just like a non-member variable, but with a name that requires to be accessed like a member of a class (or
an object).
Classes can also have static member functions. These represent the same: members of a class that are common to all
object of that class, acting exactly as non-member functions but being accessed like members of the class. Because
they are like non-member functions, they cannot access non-static members of the class (neither member variables nor
member functions). They neither can use the keyword this.
cons MyClass
myobject;
The access to its data members from outside the class is restricted to read-only, as if all its data members were cons
for those accessing them from outside the class. Note though, that the constructor is still called and is allowed to
initialize and modify these data members:
The member functions of a cons object can only be called if they are themselves specifed as cons members; in the
example above, member get (which is not specifed as cons) cannot be called from foo. To specify that a member is a
cons member, the cons keyword shall follow the function prototype, after the closing parenthesis for its parameters:
http://www.cplusplus.com/doc/tutorial/templates/[03/12/2018 00:55:23]
Classes (II) - C++ Tutorials
Note that cons can be used to qualify the type returned by a member function. This cons is not the same as the one
which specifes a member as cons. Both are independent and are located at diferent places in the function prototype:
Member functions specifed to be cons cannot modify non-static data members nor call other non-cons member
functions. In essence, cons members shall not modify the state of an object.
cons objects are limited to access only member functions marked as cons, but non-cons objects are not restricted and
thus can access both cons and non-cons member functions alike.
You may think that anyway you are seldom going to declare cons objects, and thus marking all members that don't
modify the object as const is not worth the efort, but const objects are actually very common. Most functions taking
classes as parameters actually take them by cons reference, and thus, these functions can only access their cons
members:
1 // cons objects 10
2 #include <iosream>
3 using namespace sd;
4
5 class MyClass {
6 int x;
7 public:
8 MyClass(int val) : x(val) {}
9 cons int& get() cons {return x;}
10 };
11
12 void print (cons MyClass& arg) {
13 cout << arg.get() << '\n';
14 }
15
16 int main() {
17 MyClass foo (10);
18 print(foo);
19
20 return 0;
21 }
If in this example, get was not specifed as a cons member, the call to arg.get() in the print function would not be
possible, because cons objects only have access to cons member functions.
Member functions can be overloaded on their constness: i.e., a class may have two member functions with identical
signatures except that one is cons and the other is not: in this case, the cons version is called only when the object is
itself const, and the non-cons version is called when the object is itself non-cons.
http://www.cplusplus.com/doc/tutorial/templates/[03/12/2018 00:55:23]
Classes (II) - C++ Tutorials
17 int&
18 // bar.get() = 25; // not valid: get()
19 returns cons int&
20 cout << foo.get() << '\n';
21 cout << bar.get() << '\n';
22
return 0;
}
Class templates
Just like we can create function templates, we can also create class templates, allowing classes to have members that
use template parameters as types. For example:
The class that we have just defned serves to store two elements of any valid type. For example, if we wanted to
declare an object of this class to store two integer values of type int with the values 115 and 36 we would write:
This same class could also be used to create an object to store any other type, such as:
The constructor is the only member function in the previous class template and it has been defned inline within the
class defnition itself. In case that a member function is defned outside the defntion of the class template, it shall be
preceded with the template <...> prefx:
http://www.cplusplus.com/doc/tutorial/templates/[03/12/2018 00:55:23]
Classes (II) - C++ Tutorials
Confused by so many T's? There are three T's in this declaration: The frst one is the template parameter. The second T
refers to the type returned by the function. And the third T (the one between angle brackets) is also a requirement: It
specifes that this function's template parameter is also the class template parameter.
Template specialization
It is possible to defne a diferent implementation for a template when a specifc type is passed as template argument.
This is called a template specialization.
For example, let's suppose that we have a very simple class called mycontainer that can store one element of any type
and that has just one member function called increase, which increases its value. But we fnd that when it stores an
element of type char it would be more convenient to have a completely diferent implementation with a function
member uppercase, so we decide to declare a class template specialization for that type:
1 // template specialization 8
2 #include <iosream> J
3 using namespace sd;
4
5 // class template:
6 template <class T>
7 class mycontainer {
8 T element;
9 public:
10 mycontainer (T arg) {element=arg;}
11 T increase () {return ++element;}
12 };
13
14 // class template specialization:
15 template <>
16 class mycontainer <char> {
17 char element;
18 public:
19 mycontainer (char arg) {element=arg;}
20 char uppercase ()
21 {
22 if ((element>='a')&&(element<='z'))
23 element+='A'-'a';
24 return element;
25 }
26 };
27
28 int main () {
29 mycontainer<int> myint (7);
30 mycontainer<char> mychar ('j');
31 cout << myint.increase() << endl;
32 cout << mychar.uppercase() << endl;
33 return 0;
34 }
http://www.cplusplus.com/doc/tutorial/templates/[03/12/2018 00:55:23]
Classes (II) - C++ Tutorials
First of all, notice that we precede the class name with template<> , including an empty parameter list. This is because
all types are known and no template arguments are required for this specialization, but still, it is the specialization of a
class template, and thus it requires to be noted as such.
But more important than this prefx, is the <char> specialization parameter after the class template name. This
specialization parameter itself identifes the type for which the template class is being specialized (char). Notice the
diferences between the generic class template and the specialization:
The frst line is the generic template, and the second one is the specialization.
When we declare specializations for a template class, we must also defne all its members, even those identical to the
generic template class, because there is no "inheritance" of members from the generic template to the specialization.
Previous: Next:
Classes (I) Special members
Index
http://www.cplusplus.com/doc/tutorial/templates/[03/12/2018 00:55:23]
Special members - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
http://www.cplusplus.com/doc/tutorial/classes2/[03/12/2018 00:55:45]
Special members - C++ Tutorials
Classes (I) longer provides an implicit default constructor, and no longer allows the declaration of new objects of that class without
Classes (II) arguments. For example, the following class:
Special members
Friendship and inheritance 1 class Example2 {
2 public:
Polymorphism 3 int total;
Other language features: 4 Example2 (int initial_value) : total(initial_value) { };
5 void accumulate (int x) { total += x; };
Type conversions 6 };
Exceptions
Preprocessor directives
Standard library: Here, we have declared a constructor with a parameter of type int. Therefore the following object declaration would be
Input/output with correct:
fles
Example2 ex (100); // ok: calls consructor
Would not be valid, since the class has been declared with an explicit constructor taking one argument and that
replaces the implicit default constructor taking none.
Therefore, if objects of this class need to be constructed without arguments, the proper default constructor shall also be
declared in the class. For example:
Here, Example3 has a default constructor (i.e., a constructor without parameters) defned as an empty block:
Example3()
{}
This allows objects of class Example3 to be constructed without arguments (like foo was declared in this example).
Normally, a default constructor like this is implicitly defned for all classes that have no other constructors and thus no
explicit defnition is required. But in this case, Example3 has another constructor:
http://www.cplusplus.com/doc/tutorial/classes2/[03/12/2018 00:55:45]
Special members - C++ Tutorials
And when any constructor is explicitly declared in a class, no implicit default constructors is automatically provided.
Destructor
Destructors fulfll the opposite functionality of constructors: They are responsible for the necessary cleanup needed by a
class when its lifetime ends. The classes we have defned in previous chapters did not allocate any resource and thus did
not really require any clean up.
But now, let's imagine that the class in the last example allocates dynamic memory to store the string it had as data
member; in this case, it would be very useful to have a function called automatically at the end of the object's life in
charge of releasing this memory. To do this, we use a destructor. A destructor is a member function very similar to a
default constructor: it takes no arguments and returns nothing, not even void. It also uses the class name as its own
name, but preceded with a tilde sign (~):
On construction, Example4 allocates storage for a sring. Storage that is later released by the destructor.
The destructor for an object is called at the end of its lifetime; in the case of foo and bar this happens at the end of
function main.
Copy constructor
When an object is passed a named object of its own type as argument, its copy constructor is invoked in order to
construct a copy.
A copy constructor is a constructor whose frst parameter is of type reference to the class itself (possibly cons qualifed)
and which can be invoked with a single argument of this type. For example, for a class MyClass, the copy constructor
may have the following signature:
http://www.cplusplus.com/doc/tutorial/classes2/[03/12/2018 00:55:45]
Special members - C++ Tutorials
If a class has no custom copy nor move constructors (or assignments) defned, an implicit copy constructor is provided.
This copy constructor simply performs a copy of its own members. For example, for a class such as:
1 class MyClass {
2 public:
3 int a, b; sring c;
4 };
An implicit copy constructor is automatically defned. The defnition assumed for this function performs a shallow copy,
roughly equivalent to:
This default copy constructor may suit the needs of many classes. But shallow copies only copy the members of the
class themselves, and this is probably not what we expect for classes like class Example4 we defned above, because it
contains pointers of which it handles its storage. For that class, performing a shallow copy means that the pointer value
is copied, but not the content itself; This means that both objects (the copy and the original) would be sharing a single
sring object (they would both be pointing to the same object), and at some point (on destruction) both objects would
try to delete the same block of memory, probably causing the program to crash on runtime. This can be solved by
defning the following custom copy constructor that performs a deep copy:
The deep copy performed by this copy constructor allocates storage for a new string, which is initialized to contain a
copy of the original object. In this way, both objects (copy and original) have distinct copies of the content stored in
diferent locations.
Copy assignment
Objects are not only copied on construction, when they are initialized: They can also be copied on any assignment
operation. See the diference:
1 MyClass foo;
2 MyClass bar (foo); // object initialization: copy consructor called
http://www.cplusplus.com/doc/tutorial/classes2/[03/12/2018 00:55:45]
Special members - C++ Tutorials
Note that baz is initialized on construction using an equal sign, but this is not an assignment operation! (although it
may look like one): The declaration of an object is not an assignment operation, it is just another of the syntaxes to call
single-argument constructors.
The assignment on foo is an assignment operation. No object is being declared here, but an operation is being
performed on an existing object; foo.
The copy assignment operator is an overload of operator= which takes a value or reference of the class itself as
parameter. The return value is generally a reference to *this (although this is not required). For example, for a class
MyClass, the copy assignment may have the following signature:
The copy assignment operator is also a special function and is also defned implicitly if a class has no custom copy nor
move assignments (nor move constructor) defned.
But again, the implicit version performs a shallow copy which is suitable for many classes, but not for classes with
pointers to objects they handle its storage, as is the case in Example5. In this case, not only the class incurs the risk of
deleting the pointed object twice, but the assignment creates memory leaks by not deleting the object pointed by the
object before the assignment. These issues could be solved with a copy assignment that deletes the previous object and
performs a deep copy:
Or even better, since its sring member is not constant, it could re-utilize the same sring object:
Unnamed objects are objects that are temporary in nature, and thus haven't even been given a name. Typical examples
of unnamed objects are return values of functions or type-casts.
Using the value of a temporary object such as these to initialize another object or to assign its value, does not really
require a copy: the object is never going to be used for anything else, and thus, its value can be moved into the
destination object. These cases trigger the move constructor and move assignments:
http://www.cplusplus.com/doc/tutorial/classes2/[03/12/2018 00:55:45]
Special members - C++ Tutorials
The move constructor is called when an object is initialized on construction using an unnamed temporary. Likewise, the
move assignment is called when an object is assigned the value of an unnamed temporary:
Both the value returned by fn and the value constructed with MyClass are unnamed temporaries. In these cases, there
is no need to make a copy, because the unnamed object is very short-lived and can be acquired by the other object
when this is a more efcient operation.
The move constructor and move assignment are members that take a parameter of type rvalue reference to the class
itself:
An rvalue reference is specifed by following the type with two ampersands (&&). As a parameter, an rvalue reference
matches arguments of temporaries of this type.
The concept of moving is most useful for objects that manage the storage they use, such as objects that allocate
storage with new and delete. In such objects, copying and moving are really diferent operations:
- Copying from A to B means that new memory is allocated to B and then the entire content of A is copied to this new
memory allocated for B.
- Moving from A to B means that the memory already allocated to A is transferred to B without allocating any new
storage. It involves simply copying the pointer.
For example:
1 // move consructor/assignment foo's content: Example
2 #include <iosream>
3 #include <sring>
4 using namespace sd;
5
6 class Example6 {
7 sring* ptr;
8 public:
9 Example6 (cons sring& sr) : ptr(new
10 sring(sr)) {}
11 ~Example6 () {delete ptr;}
12 // move consructor
13 Example6 (Example6&& x) : ptr(x.ptr)
14 {x.ptr=nullptr;}
15 // move assignment
16 Example6& operator= (Example6&& x) {
17 delete ptr;
18 ptr = x.ptr;
19 x.ptr=nullptr;
20 return *this;
21 }
22 // access content:
23 cons sring& content() cons {return *ptr;}
24 // addition:
25 Example6 operator+(cons Example6& rhs) {
26 return Example6(content()+rhs.content());
27 }
28 };
29
30
31 int main () {
http://www.cplusplus.com/doc/tutorial/classes2/[03/12/2018 00:55:45]
Special members - C++ Tutorials
Compilers already optimize many cases that formally require a move-construction call in what is known as Return Value
Optimization. Most notably, when the value returned by a function is used to initialize an object. In these cases, the
move constructor may actually never get called.
Note that even though rvalue references can be used for the type of any function parameter, it is seldom useful for uses
other than the move constructor. Rvalue references are tricky, and unnecessary uses may be the source of errors quite
difcult to track.
Implicit members
The six special members functions described above are members implicitly declared on classes under certain
circumstances:
Notice how not all special member functions are implicitly defned in the same cases. This is mostly due to backwards
compatibility with C structures and earlier C++ versions, and in fact some include deprecated cases. Fortunately, each
class can select explicitly which of these members exist with their default defnition or which are deleted by using the
keywords default and delete, respectively. The syntax is either one of:
function_declaration = default;
function_declaration = delete;
For example:
1 // default and delete implicit members bar's area: 200
2 #include <iosream>
3 using namespace sd;
4
5 class Rectangle {
6 int width, height;
7 public:
8 Rectangle (int x, int y) : width(x),
9 height(y) {}
10 Rectangle() = default;
11 Rectangle (cons Rectangle& other) = delete;
12 int area() {return width*height;}
13 };
14
15 int main () {
16 Rectangle foo;
17 Rectangle bar (10,20);
18
19 cout << "bar's area: " << bar.area() << '\n';
http://www.cplusplus.com/doc/tutorial/classes2/[03/12/2018 00:55:45]
Special members - C++ Tutorials
20 return 0;
}
Here, Rectangle can be constructed either with two int arguments or be default-constructed (with no arguments). It
cannot however be copy-constructed from another Rectangle object, because this function has been deleted.
Therefore, assuming the objects of the last example, the following statement would not be valid:
It could, however, be made explicitly valid by defning its copy constructor as:
Note that, the keyword default does not defne a member function equal to the default constructor (i.e., where default
constructor means constructor with no parameters), but equal to the constructor that would be implicitly defned if not
deleted.
In general, and for future compatibility, classes that explicitly defne one copy/move constructor or one copy/move
assignment but not both, are encouraged to specify either delete or default on the other special member functions
they don't explicitly defne.
Previous: Next:
Classes (II) Friendship and inheritance
Index
http://www.cplusplus.com/doc/tutorial/classes2/[03/12/2018 00:55:45]
Friendship and inheritance - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
http://www.cplusplus.com/doc/tutorial/inheritance/[03/12/2018 00:56:06]
Friendship and inheritance - C++ Tutorials
Classes (I) isn't! It simply has access to its private and protected members without being a member.
Classes (II)
Special members Typical use cases of friend functions are operations that are conducted between two diferent classes accessing private
Friendship and inheritance or protected members of both.
Polymorphism
Other language features:
Type conversions
Friend classes
Exceptions Similar to friend functions, a friend class is a class whose members have access to the private or protected members of
Preprocessor directives another class:
Standard library:
1 // friend class 16
Input/output with 2 #include <iosream>
fles 3 using namespace sd;
4
5 class Square;
6
7 class Rectangle {
8 int width, height;
9 public:
10 int area ()
11 {return (width * height);}
12 void convert (Square a);
13 };
14
15 class Square {
16 friend class Rectangle;
17 private:
18 int side;
19 public:
20 Square (int a) : side(a) {}
21 };
22
23 void Rectangle::convert (Square a) {
24 width = a.side;
25 height = a.side;
26 }
27
28 int main () {
29 Rectangle rect;
30 Square sqr (4);
31 rect.convert(sqr);
32 cout << rect.area();
33 return 0;
34 }
In this example, class Rectangle is a friend of class Square allowing Rectangle's member functions to access private
and protected members of Square. More concretely, Rectangle accesses the member variable Square::side, which
describes the side of the square.
There is something else new in this example: at the beginning of the program, there is an empty declaration of class
Square. This is necessary because class Rectangle uses Square (as a parameter in member convert), and Square uses
Rectangle (declaring it a friend).
Friendships are never corresponded unless specifed: In our example, Rectangle is considered a friend class by Square,
but Square is not considered a friend by Rectangle. Therefore, the member functions of Rectangle can access the
protected and private members of Square but not the other way around. Of course, Square could also be declared
friend of Rectangle, if needed, granting such an access.
Another property of friendships is that they are not transitive: The friend of a friend is not considered a friend unless
explicitly specifed.
http://www.cplusplus.com/doc/tutorial/inheritance/[03/12/2018 00:56:06]
Friendship and inheritance - C++ Tutorials
Classes in C++ can be extended, creating new classes which retain characteristics of the base class. This process,
known as inheritance, involves a base class and a derived class: The derived class inherits the members of the base
class, on top of which it can add its own members.
For example, let's imagine a series of classes to describe two kinds of polygons: rectangles and triangles. These two
polygons have certain common properties, such as the values needed to calculate their areas: they both can be
described simply with a height and a width (or base).
This could be represented in the world of classes with a class Polygon from which we would derive the two other ones:
Rectangle and Triangle:
The Polygon class would contain members that are common for both types of polygon. In our case: width and height.
And Rectangle and Triangle would be its derived classes, with specifc features that are diferent from one type of
polygon to the other.
Classes that are derived from others inherit all the accessible members of the base class. That means that if a base
class includes a member A and we derive a class from it with another member calledB, the derived class will contain
both member A and member B.
The inheritance relationship of two classes is declared in the derived class. Derived classes defnitions use the following
syntax:
Where derived_class_name is the name of the derived class and base_class_name is the name of the class on which it
is based. The public access specifer may be replaced by any one of the other access specifers (protected or
private). This access specifer limits the most accessible level for the members inherited from the base class: The
members with a more accessible level are inherited with this level instead, while the members with an equal or more
restrictive access level keep their restrictive level in the derived class.
1 // derived classes 20
2 #include <iosream> 10
3 using namespace sd;
4
5 class Polygon {
6 protected:
7 int width, height;
8 public:
9 void set_values (int a, int b)
10 { width=a; height=b;}
11 };
12
13 class Rectangle: public Polygon {
14 public:
15 int area ()
16 { return width * height; }
17 };
18
19 class Triangle: public Polygon {
20 public:
http://www.cplusplus.com/doc/tutorial/inheritance/[03/12/2018 00:56:06]
Friendship and inheritance - C++ Tutorials
21 int area ()
22 { return width * height / 2; }
23 };
24
25 int main () {
26 Rectangle rect;
27 Triangle trgl;
28 rect.set_values (4,5);
29 trgl.set_values (4,5);
30 cout << rect.area() << '\n';
31 cout << trgl.area() << '\n';
32 return 0;
33 }
The objects of the classes Rectangle and Triangle each contain members inherited from Polygon. These are: width,
height and set_values.
The protected access specifer used in class Polygon is similar to private. Its only diference occurs in fact with
inheritance: When a class inherits another one, the members of the derived class can access the protected members
inherited from the base class, but not its private members.
By declaring width and height as protected instead of private, these members are also accessible from the derived
classes Rectangle and Triangle, instead of just from members of Polygon. If they were public, they could be accessed
just from anywhere.
We can summarize the diferent access types according to which functions can access them in the following way:
Where "not members" represents any access from outside the class, such as from main, from another class or from a
function.
In the example above, the members inherited by Rectangle and Triangle have the same access permissions as they
had in their base class Polygon:
This is because the inheritance relation has been declared using the public keyword on each of the derived classes:
This public keyword after the colon (:) denotes the most accessible level the members inherited from the class that
follows it (in this case Polygon) will have from the derived class (in this case Rectangle). Since public is the most
accessible level, by specifying this keyword the derived class will inherit all the members with the same levels they had
in the base class.
With protected, all public members of the base class are inherited asprotected in the derived class. Conversely, if
http://www.cplusplus.com/doc/tutorial/inheritance/[03/12/2018 00:56:06]
Friendship and inheritance - C++ Tutorials
the most restricting access level is specifed (private), all the base class members are inherited asprivate.
For example, if daughter were a class derived from mother that we defned as:
This would set protected as the less restrictive access level for the members of Daughter that it inherited from
mother. That is, all members that were public in Mother would become protected in Daughter. Of course, this would
not restrict Daughter from declaring its own public members. That less restrictive access level is only set for the
members inherited from Mother.
If no access level is specifed for the inheritance, the compiler assumes private for classes declared with keyword class
and public for those declared with sruct.
Actually, most use cases of inheritance in C++ should use public inheritance. When other access levels are needed for
base classes, they can usually be better represented as member variables instead.
Even though access to the constructors and destructor of the base class is not inherited as such, they are automatically
called by the constructors and destructor of the derived class.
Unless otherwise specifed, the constructors of a derived class calls the default constructor of its base classes (i.e., the
constructor taking no arguments). Calling a diferent constructor of a base class is possible, using the same syntax used
to initialize member variables in the initialization list:
For example:
http://www.cplusplus.com/doc/tutorial/inheritance/[03/12/2018 00:56:06]
Friendship and inheritance - C++ Tutorials
Notice the diference between which Mother's constructor is called when a new Daughter object is created and which
when it is a Son object. The diference is due to the diferent constructor declarations of Daughter and Son:
Multiple inheritance
A class may inherit from more than one class by simply specifying more base classes, separated by commas, in the list
of a class's base classes (i.e., after the colon). For example, if the program had a specifc class to print on screen called
Output, and we wanted our classes Rectangle and Triangle to also inherit its members in addition to those of Polygon
we could write:
1 // multiple inheritance 20
2 #include <iosream> 10
3 using namespace sd;
4
5 class Polygon {
6 protected:
7 int width, height;
8 public:
9 Polygon (int a, int b) : width(a),
10 height(b) {}
11 };
12
13 class Output {
14 public:
15 satic void print (int i);
16 };
17
18 void Output::print (int i) {
19 cout << i << '\n';
20 }
21
22 class Rectangle: public Polygon, public Output {
23 public:
24 Rectangle (int a, int b) : Polygon(a,b) {}
25 int area ()
26 { return width*height; }
27 };
28
29 class Triangle: public Polygon, public Output {
30 public:
31 Triangle (int a, int b) : Polygon(a,b) {}
32 int area ()
33 { return width*height/2; }
34 };
35
36 int main () {
http://www.cplusplus.com/doc/tutorial/inheritance/[03/12/2018 00:56:06]
Friendship and inheritance - C++ Tutorials
Previous: Next:
Special members Polymorphism
Index
http://www.cplusplus.com/doc/tutorial/inheritance/[03/12/2018 00:56:06]
Polymorphism - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
Tutorials Polymorphism
C++ Language Before getting any deeper into this chapter, you should have a proper understanding of pointers and class inheritance.
Ascii If you are not really sure of the meaning of any of the following expressions, you should review the indicated sections:
Codes
Boolean Operations Statement: Explained in:
Numerical Bases int A::b(int c) { } Classes
a->b Data structures
C++ Language
class A: public B
Introduction: Friendship and inheritance
{};
Compilers
Basics of C++:
Structure of a Pointers to base class
program
One of the key features of class inheritance is that a pointer to a derived class is type-compatible with a pointer to its
Variables and types base class. Polymorphism is the art of taking advantage of this simple but powerful and versatile feature.
Consants
Operators The example about the rectangle and triangle classes can be rewritten using pointers taking this feature into account:
Basic Input/Output
Program sructure: 1 // pointers to base class 20
2 #include <iosream> 10
Statements and fow 3 using namespace sd;
4
control 5 class Polygon {
Functions 6 protected:
7 int width, height;
Overloads and 8 public:
templates 9 void set_values (int a, int b)
10 { width=a; height=b; }
Name 11 };
12
visibility 13 class Rectangle: public Polygon {
Compound data types: 14 public:
15 int area()
Arrays 16 { return width*height; }
Character sequences 17 };
18
Pointers 19 class Triangle: public Polygon {
20 public:
Dynamic memory 21 int area()
Data 22 { return width*height/2; }
23 };
sructures 24
Other data 25 int main () {
26 Rectangle rect;
types 27 Triangle trgl;
28 Polygon * ppoly1 = ▭
Classes: 29 Polygon * ppoly2 = &trgl;
http://www.cplusplus.com/doc/tutorial/polymorphism/[03/12/2018 00:56:30]
Polymorphism - C++ Tutorials
But because the type of ppoly1 and ppoly2 is pointer to Polygon (and not pointer to Rectangle nor pointer to
Triangle), only the members inherited from Polygon can be accessed, and not those of the derived classes Rectangle
and Triangle. That is why the program above accesses the area members of both objects using rect and trgl
directly, instead of the pointers; the pointers to the base class cannot access the area members.
Member area could have been accessed with the pointers to Polygon if area were a member of Polygon instead of a
member of its derived classes, but the problem is that Rectangle and Triangle implement diferent versions of area,
therefore there is not a single common version that could be implemented in the base class.
Virtual members
A virtual member is a member function that can be redefned in a derived class, while preserving its calling properties
through references. The syntax for a function to become virtual is to precede its declaration with the virtual keyword:
1 // virtual members 20
2 #include <iosream> 10
3 using namespace sd; 0
4
5 class Polygon {
6 protected:
7 int width, height;
8 public:
9 void set_values (int a, int b)
10 { width=a; height=b; }
11 virtual int area ()
12 { return 0; }
13 };
14
15 class Rectangle: public Polygon {
16 public:
17 int area ()
18 { return width * height; }
19 };
20
21 class Triangle: public Polygon {
22 public:
23 int area ()
24 { return (width * height / 2); }
25 };
26
27 int main () {
28 Rectangle rect;
29 Triangle trgl;
30 Polygon poly;
31 Polygon * ppoly1 = ▭
32 Polygon * ppoly2 = &trgl;
33 Polygon * ppoly3 = &poly;
http://www.cplusplus.com/doc/tutorial/polymorphism/[03/12/2018 00:56:30]
Polymorphism - C++ Tutorials
34 ppoly1->set_values (4,5);
35 ppoly2->set_values (4,5);
36 ppoly3->set_values (4,5);
37 cout << ppoly1->area() << '\n';
38 cout << ppoly2->area() << '\n';
39 cout << ppoly3->area() << '\n';
40 return 0;
41 }
In this example, all three classes (Polygon, Rectangle and Triangle) have the same members: width, height, and
functions set_values and area.
The member function area has been declared as virtual in the base class because it is later redefned in each of the
derived classes. Non-virtual members can also be redefned in derived classes, but non-virtual members of derived
classes cannot be accessed through a reference of the base class: i.e., if virtual is removed from the declaration of
area in the example above, all three calls to area would return zero, because in all cases, the version of the base class
would have been called instead.
Therefore, essentially, what the virtual keyword does is to allow a member of a derived class with the same name as
one in the base class to be appropriately called from a pointer, and more precisely when the type of the pointer is a
pointer to the base class that is pointing to an object of the derived class, as in the above example.
Note that despite of the virtuality of one of its members, Polygon was a regular class, of which even an object was
instantiated (poly), with its own defnition of member area that always returns 0.
Notice that area has no defnition; this has been replaced by =0, which makes it a pure virtual function. Classes that
contain at least one pure virtual function are known as abstract base classes.
Abstract base classes cannot be used to instantiate objects. Therefore, this last abstract base class version of Polygon
could not be used to declare objects like:
But an abstract base class is not totally useless. It can be used to create pointers to it, and take advantage of all its
polymorphic abilities. For example, the following pointer declarations would be valid:
http://www.cplusplus.com/doc/tutorial/polymorphism/[03/12/2018 00:56:30]
Polymorphism - C++ Tutorials
1 Polygon * ppoly1;
2 Polygon * ppoly2;
And can actually be dereferenced when pointing to objects of derived (non-abstract) classes. Here is the entire
example:
In this example, objects of diferent but related types are referred to using a unique type of pointer (Polygon*) and the
proper member function is called every time, just because they are virtual. This can be really useful in some
circumstances. For example, it is even possible for a member of the abstract base class Polygon to use the special
pointer this to access the proper virtual members, even though Polygon itself has no implementation for this function:
http://www.cplusplus.com/doc/tutorial/polymorphism/[03/12/2018 00:56:30]
Polymorphism - C++ Tutorials
Virtual members and abstract classes grant C++ polymorphic characteristics, most useful for object-oriented projects.
Of course, the examples above are very simple use cases, but these features can be applied to arrays of objects or
dynamically allocated objects.
Here is an example that combines some of the features in the latest chapters, such as dynamic memory, constructor
initializers and polymorphism:
http://www.cplusplus.com/doc/tutorial/polymorphism/[03/12/2018 00:56:30]
Polymorphism - C++ Tutorials
are declared being of type "pointer to Polygon", but the objects allocated have been declared having the derived class
type directly (Rectangle and Triangle).
Previous: Next:
Friendship and inheritance Type conversions
Index
http://www.cplusplus.com/doc/tutorial/polymorphism/[03/12/2018 00:56:30]
Type conversions - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
http://www.cplusplus.com/doc/tutorial/typecasting/[03/12/2018 00:56:51]
Type conversions - C++ Tutorials
Classes (I)
Classes (II)
Special members
Friendship and inheritance Implicit conversions with classes
Polymorphism
In the world of classes, implicit conversions can be controlled by means of three member functions:
Other language features:
Type conversions Single-argument constructors: allow implicit conversion from a particular type to initialize an object.
Exceptions Assignment operator: allow implicit conversion from a particular type on assignments.
Preprocessor directives Type-cast operator: allow implicit conversion to a particular type.
Standard library:
Input/output with For example:
fles
1 // implicit conversion of classes:
2 #include <iosream>
3 using namespace sd;
4
5 class A {};
6
7 class B {
8 public:
9 // conversion from A (consructor):
10 B (cons A& x) {}
11 // conversion from A (assignment):
12 B& operator= (cons A& x) {return *this;}
13 // conversion to A (type-cas operator)
14 operator A() {return A();}
15 };
16
17 int main ()
18 {
19 A foo;
20 B bar = foo; // calls consructor
21 bar = foo; // calls assignment
22 foo = bar; // calls type-cas operator
23 return 0;
24 }
The type-cast operator uses a particular syntax: it uses the operator keyword followed by the destination type and an
empty set of parentheses. Notice that the return type is the destination type and thus is not specifed before the
operator keyword.
Keyword explicit
On a function call, C++ allows one implicit conversion to happen for each argument. This may be somewhat
problematic for classes, because it is not always what is intended. For example, if we add the following function to the
last example:
void fn (B arg)
{}
This function takes an argument of type B, but it could as well be called with an object of type A as argument:
fn (foo);
This may or may not be what was intended. But, in any case, it can be prevented by marking the afected constructor
with the explicit keyword:
http://www.cplusplus.com/doc/tutorial/typecasting/[03/12/2018 00:56:51]
Type conversions - C++ Tutorials
1 // explicit:
2 #include <iosream>
3 using namespace sd;
4
5 class A {};
6
7 class B {
8 public:
9 explicit B (cons A& x) {}
10 B& operator= (cons A& x) {return *this;}
11 operator A() {return A();}
12 };
13
14 void fn (B x) {}
15
16 int main ()
17 {
18 A foo;
19 B bar (foo);
20 bar = foo;
21 foo = bar;
22
23 // fn (foo); // not allowed for explicit
24 ctor.
25 fn (bar);
26
27 return 0;
}
Additionally, constructors marked with explicit cannot be called with the assignment-like syntax; In the above
example, bar could not have been constructed with:
B bar = foo;
Type-cast member functions (those described in the previous section) can also be specifed as explicit. This prevents
implicit conversions in the same way as explicit-specifed constructors do for the destination type.
Type casting
C++ is a strong-typed language. Many conversions, specially those that imply a diferent interpretation of the value,
require an explicit conversion, known in C++ as type-casting. There exist two main syntaxes for generic type-casting:
functional and c-like:
1 double x = 10.3;
2 int y;
3 y = int (x); // functional notation
4 y = (int) x; // c-like cas notation
The functionality of these generic forms of type-casting is enough for most needs with fundamental data types.
However, these operators can be applied indiscriminately on classes and pointers to classes, which can lead to code that
-while being syntactically correct- can cause runtime errors. For example, the following code compiles without errors:
1 // class type-casing
2 #include <iosream>
3 using namespace sd;
4
5 class Dummy {
6 double i,j;
7 };
8
9 class Addition {
10 int x,y;
11 public:
http://www.cplusplus.com/doc/tutorial/typecasting/[03/12/2018 00:56:51]
Type conversions - C++ Tutorials
The program declares a pointer to Addition, but then it assigns to it a reference to an object of another unrelated type
using explicit type-casting:
Unrestricted explicit type-casting allows to convert any pointer into any other pointer type, independently of the types
they point to. The subsequent call to member result will produce either a run-time error or some other unexpected
results.
In order to control these types of conversions between classes, we have four specifc casting operators: dynamic_cas,
reinterpret_cas, satic_cas and cons_cas. Their format is to follow the new type enclosed between angle-brackets
(<>) and immediately after, the expression to be converted between parentheses.
(new_type) expression
new_type (expression)
dynamic_cast
dynamic_cas can only be used with pointers and references to classes (or withvoid*). Its purpose is to ensure that the
result of the type conversion points to a valid complete object of the destination pointer type.
This naturally includes pointer upcast (converting from pointer-to-derived to pointer-to-base), in the same way as
allowed as an implicit conversion.
But dynamic_cas can also downcast (convert from pointer-to-base to pointer-to-derived) polymorphic classes (those
with virtual members) if -and only if- the pointed object is a valid complete object of the target type. For example:
http://www.cplusplus.com/doc/tutorial/typecasting/[03/12/2018 00:56:51]
Type conversions - C++ Tutorials
Compatibility note: This type of dynamic_cas requires Run-Time Type Information (RTTI) to keep track of dynamic
types. Some compilers support this feature as an option which is disabled by default. This needs to be enabled for
runtime type checking using dynamic_cas to work properly with these types.
The code above tries to perform two dynamic casts from pointer objects of type Base* (pba and pbb) to a pointer object
of type Derived*, but only the frst one is successful. Notice their respective initializations:
Even though both are pointers of type Base*, pba actually points to an object of type Derived, while pbb points to an
object of type Base. Therefore, when their respective type-casts are performed using dynamic_cas, pba is pointing to a
full object of class Derived, whereas pbb is pointing to an object of class Base, which is an incomplete object of class
Derived.
When dynamic_cas cannot cast a pointer because it is not a complete object of the required class -as in the second
conversion in the previous example- it returns a null pointer to indicate the failure. If dynamic_cas is used to convert to
a reference type and the conversion is not possible, an exception of type bad_cas is thrown instead.
dynamic_cas can also perform the other implicit casts allowed on pointers: casting null pointers between pointers types
(even between unrelated classes), and casting any pointer of any type to a void* pointer.
static_cast
satic_cas can perform conversions between pointers to related classes, not only upcasts (from pointer-to-derived to
pointer-to-base), but also downcasts (from pointer-to-base to pointer-to-derived). No checks are performed during
runtime to guarantee that the object being converted is in fact a full object of the destination type. Therefore, it is up to
the programmer to ensure that the conversion is safe. On the other side, it does not incur the overhead of the type-
safety checks of dynamic_cas.
This would be valid code, although b would point to an incomplete object of the class and could lead to runtime errors if
dereferenced.
Therefore, satic_cas is able to perform with pointers to classes not only the conversions allowed implicitly, but also
their opposite conversions.
http://www.cplusplus.com/doc/tutorial/typecasting/[03/12/2018 00:56:51]
Type conversions - C++ Tutorials
satic_cas is also able to perform all conversions allowed implicitly (not only those with pointers to classes), and is also
able to perform the opposite of these. It can:
Convert from void* to any pointer type. In this case, it guarantees that if the void* value was obtained by
converting from that same pointer type, the resulting pointer value is the same.
Convert integers, foating-point values and enum types to enum types.
reinterpret_cast
reinterpret_cas converts any pointer type to any other pointer type, even of unrelated classes. The operation result
is a simple binary copy of the value from one pointer to the other. All pointer conversions are allowed: neither the
content pointed nor the pointer type itself is checked.
It can also cast pointers to or from integer types. The format in which this integer value represents a pointer is
platform-specifc. The only guarantee is that a pointer cast to an integer type large enough to fully contain it (such as
intptr_t), is guaranteed to be able to be cast back to a valid pointer.
The conversions that can be performed by reinterpret_cas but not by satic_cas are low-level operations based on
reinterpreting the binary representations of the types, which on most cases results in code which is system-specifc,
and thus non-portable. For example:
1 class A { /* ... */ };
2 class B { /* ... */ };
3 A * a = new A;
4 B * b = reinterpret_cas<B*>(a);
This code compiles, although it does not make much sense, since now b points to an object of a totally unrelated and
likely incompatible class. Dereferencing b is unsafe.
const_cast
This type of casting manipulates the constness of the object pointed by a pointer, either to be set or to be removed.
For example, in order to pass a const pointer to a function that expects a non-const argument:
http://www.cplusplus.com/doc/tutorial/typecasting/[03/12/2018 00:56:51]
Type conversions - C++ Tutorials
The example above is guaranteed to work because function print does not write to the pointed object. Note though,
that removing the constness of a pointed object to actually write to it causes undefned behavior.
typeid
typeid allows to check the type of an expression:
typeid (expression)
This operator returns a reference to a constant object of type type_info that is defned in the standard header
<typeinfo>. A value returned by typeid can be compared with another value returned by typeid using operators ==
and != or can serve to obtain a null-terminated character sequence representing the data type or class name by using
its name() member.
When typeid is applied to classes, typeid uses the RTTI to keep track of the type of dynamic objects. When typeid is
applied to an expression whose type is a polymorphic class, the result is the type of the most derived complete object:
http://www.cplusplus.com/doc/tutorial/typecasting/[03/12/2018 00:56:51]
Type conversions - C++ Tutorials
Note: The string returned by member name of type_info depends on the specifc implementation of your compiler and
library. It is not necessarily a simple string with its typical type name, like in the compiler used to produce this output.
Notice how the type that typeid considers for pointers is the pointer type itself (both a and b are of type class Base
*). However, when typeid is applied to objects (like *a and *b) typeid yields their dynamic type (i.e. the type of their
most derived complete object).
If the type typeid evaluates is a pointer preceded by the dereference operator (*), and this pointer has a null value,
typeid throws a bad_typeid exception.
Previous: Next:
Polymorphism Exceptions
Index
http://www.cplusplus.com/doc/tutorial/typecasting/[03/12/2018 00:56:51]
Exceptions - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
Tutorials Exceptions
C++ Language Exceptions provide a way to react to exceptional circumstances (like runtime errors) in programs by transferring control
Ascii to special functions called handlers.
Codes
Boolean Operations To catch exceptions, a portion of code is placed under exception inspection. This is done by enclosing that portion of
Numerical Bases code in a try-block. When an exceptional circumstance arises within that block, an exception is thrown that transfers the
control to the exception handler. If no exception is thrown, the code continues normally and all handlers are ignored.
C++ Language
An exception is thrown by using the throw keyword from inside the try block. Exception handlers are declared with the
Introduction:
keyword catch, which must be placed immediately after the try block:
Compilers
Basics of C++: 1 // exceptions An exception occurred. Exception Nr. 20
Structure of a 2 #include <iosream>
3 using namespace sd;
program 4
5 int main () {
Variables and types 6 try
Consants 7 {
8 throw 20;
Operators 9 }
Basic Input/Output 10 catch (int e)
11 {
Program sructure: 12 cout << "An exception occurred. Exception
13 Nr. " << e << '\n';
Statements and fow 14 }
control 15 return 0;
}
Functions
Overloads and
templates
The code under exception handling is enclosed in a try block. In this example this code simply throws an exception:
Name
visibility throw 20;
Compound data types:
Arrays
Character sequences A throw expression accepts one parameter (in this case the integer value 20), which is passed as an argument to the
Pointers exception handler.
Dynamic memory
The exception handler is declared with the catch keyword immediately after the closing brace of the try block. The
Data
syntax for catch is similar to a regular function with one parameter. The type of this parameter is very important, since
sructures
the type of the argument passed by the throw expression is checked against it, and only in the case they match, the
Other data exception is caught by that handler.
types
Classes: Multiple handlers (i.e., catch expressions) can be chained; each one with a diferent parameter type. Only the handler
http://www.cplusplus.com/doc/tutorial/exceptions/[03/12/2018 00:57:12]
Exceptions - C++ Tutorials
Classes (I) whose argument type matches the type of the exception specifed in the throw statement is executed.
Classes (II)
Special members
If an ellipsis (...) is used as the parameter of catch, that handler will catch any exception no matter what the type of
the exception thrown. This can be used as a default handler that catches all exceptions not caught by other handlers:
Friendship and inheritance
Polymorphism 1 try {
Other language features: 2 // code here
3 }
Type conversions 4 catch (int param) { cout << "int exception"; }
Exceptions 5 catch (char param) { cout << "char exception"; }
6 catch (...) { cout << "default exception"; }
Preprocessor directives
Standard library:
Input/output with In this case, the last handler would catch any exception thrown of a type that is neither int nor char.
fles
After an exception has been handled the program, execution resumes after the try-catch block, not after the throw
statement!.
It is also possible to nest try-catch blocks within more external try blocks. In these cases, we have the possibility
that an internal catch block forwards the exception to its external level. This is done with the expression throw; with
no arguments. For example:
1 try {
2 try {
3 // code here
4 }
5 catch (int n) {
6 throw;
7 }
8 }
9 catch (...) {
10 cout << "Exception occurred";
11 }
Exception specifcation
Older code may contain dynamic exception specifcations. They are now deprecated in C++, but still supported. A
dynamic exception specifcation follows the declaration of a function, appending a throw specifer to it. For example:
This declares a function called myfunction, which takes one argument of type char and returns a value of type double.
If this function throws an exception of some type other than int, the function calls sd::unexpected instead of looking
for a handler or calling sd::terminate.
If this throw specifer is left empty with no type, this means that sd::unexpected is called for any exception. Functions
with no throw specifer (regular functions) never call sd::unexpected, but follow the normal path of looking for their
exception handler.
Standard exceptions
The C++ Standard library provides a base class specifcally designed to declare objects to be thrown as exceptions. It is
http://www.cplusplus.com/doc/tutorial/exceptions/[03/12/2018 00:57:12]
Exceptions - C++ Tutorials
called sd::exception and is defned in the <exception> header. This class has a virtual member function called what
that returns a null-terminated character sequence (of type char *) and that can be overwritten in derived classes to
contain some sort of description of the exception.
We have placed a handler that catches exception objects by reference (notice the ampersand & after the type),
therefore this catches also classes derived from exception, like our myex object of type myexception.
All exceptions thrown by components of the C++ Standard library throw exceptions derived from this exception class.
These are:
exception description
bad_alloc thrown by new on allocation failure
thrown by dynamic_cas when it fails in a dynamic
bad_cas
cast
bad_exception thrown by certain dynamic exception specifers
bad_typeid thrown by typeid
bad_function_call thrown by empty function objects
bad_weak_ptr thrown by shared_ptr when passed a bad weak_ptr
Also deriving from exception, header <exception> defnes two generic exception types that can be inherited by
custom exceptions to report errors:
exception description
error related to the internal logic of the
logic_error
program
runtime_error error detected during runtime
A typical example where standard exceptions need to be checked for is on memory allocation:
http://www.cplusplus.com/doc/tutorial/exceptions/[03/12/2018 00:57:12]
Exceptions - C++ Tutorials
8 {
9 int* myarray= new int[1000];
10 }
11 catch (exception& e)
12 {
13 cout << "Standard exception: " << e.what()
14 << endl;
15 }
16 return 0;
}
The exception that may be caught by the exception handler in this example is a bad_alloc. Because bad_alloc is
derived from the standard base class exception, it can be caught (capturing by reference, captures all related classes).
Previous: Next:
Type conversions Preprocessor directives
Index
http://www.cplusplus.com/doc/tutorial/exceptions/[03/12/2018 00:57:12]
Preprocessor directives - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
http://www.cplusplus.com/doc/tutorial/preprocessor/[03/12/2018 00:57:37]
Preprocessor directives - C++ Tutorials
1 int table1[100];
2 int table2[200];
Function macro defnitions accept two special operators (# and ##) in the replacement sequence:
The operator #, followed by a parameter name, is replaced by a string literal that contains the argument passed (as if
enclosed between double quotes):
1 #defne sr(x) #x
2 cout <<
sr(tes);
cout <<
"tes";
The operator ## concatenates two arguments leaving no blank spaces between them:
1 #defne glue(a,b) a ##
2b
glue(c,out) << "tes";
cout <<
"tes";
Because preprocessor replacements happen before any C++ syntax check, macro defnitions can be a tricky feature.
But, be careful: code that relies heavily on complicated macros become less readable, since the syntax expected is on
http://www.cplusplus.com/doc/tutorial/preprocessor/[03/12/2018 00:57:37]
Preprocessor directives - C++ Tutorials
many occasions diferent from the normal expressions programmers expect in C++.
These directives allow to include or discard part of the code of a program if a certain condition is met.
#ifdef allows a section of a program to be compiled only if the macro that is specifed as the parameter has been
defned, no matter which its value is. For example:
1 #ifdef TABLE_SIZE
2 int table[TABLE_SIZE];
3 #endif
In this case, the line of code int table[TABLE_SIZE]; is only compiled if TABLE_SIZE was previously defned with
#defne, independently of its value. If it was not defned, that line will not be included in the program compilation.
#ifndef serves for the exact opposite: the code between #ifndef and #endif directives is only compiled if the
specifed identifer has not been previously defned. For example:
1 #ifndef TABLE_SIZE
2 #defne TABLE_SIZE 100
3 #endif
4 int table[TABLE_SIZE];
In this case, if when arriving at this piece of code, the TABLE_SIZE macro has not been defned yet, it would be defned
to a value of 100. If it already existed it would keep its previous value since the #defne directive would not be
executed.
The #if, #else and #elif (i.e., "else if") directives serve to specify some condition to be met in order for the portion of
code they surround to be compiled. The condition that follows #if or #elif can only evaluate constant expressions,
including macro expressions. For example:
1 #if TABLE_SIZE>200
2 #undef TABLE_SIZE
3 #defne TABLE_SIZE 200
4
5 #elif TABLE_SIZE<50
6 #undef TABLE_SIZE
7 #defne TABLE_SIZE 50
8
9 #else
10 #undef TABLE_SIZE
11 #defne TABLE_SIZE 100
12 #endif
13
14 int table[TABLE_SIZE];
Notice how the entire structure of #if, #elif and #else chained directives ends with #endif.
The behavior of #ifdef and #ifndef can also be achieved by using the special operators defned and !defned
respectively in any #if or #elif directive:
http://www.cplusplus.com/doc/tutorial/preprocessor/[03/12/2018 00:57:37]
Preprocessor directives - C++ Tutorials
The #line directive allows us to control both things, the line numbers within the code fles as well as the fle name that
we want that appears when an error takes place. Its format is:
Where number is the new line number that will be assigned to the next code line. The line numbers of successive lines
will be increased one by one from this point on.
"flename" is an optional parameter that allows to redefne the fle name that will be shown. For example:
1 #line 20 "assigning
2 variable"
int a?;
This code will generate an error that will be shown as error in fle "assigning variable", line 20.
1 #ifndef __cplusplus
2 #error A C++ compiler is
3 required!
#endif
This example aborts the compilation process if the macro name __cplusplus is not defned (this macro name is
defned by default in all C++ compilers).
1 #include <header>
2 #include "fle"
In the frst case, a header is specifed between angle-brackets <>. This is used to include headers provided by the
implementation, such as the headers that compose the standard library (iosream, sring,...). Whether the headers are
actually fles or exist in some other form is implementation-defned, but in any case they shall be properly included with
this directive.
http://www.cplusplus.com/doc/tutorial/preprocessor/[03/12/2018 00:57:37]
Preprocessor directives - C++ Tutorials
The syntax used in the second #include uses quotes, and includes a fle. The fle is searched for in an implementation-
defned manner, which generally includes the current path. In the case that the fle is not found, the compiler
interprets the directive as a header inclusion, just as if the quotes ("") were replaced by angle-brackets (<>).
If the compiler does not support a specifc argument for #pragma, it is ignored - no syntax error is generated.
macro value
__LINE__ Integer value representing the current line in the source code fle being compiled.
__FILE__ A string literal containing the presumed name of the source fle being compiled.
A string literal in the form "Mmm dd yyyy" containing the date in which the compilation process
__DATE__
began.
__TIME__ A string literal in the form "hh:mm:ss" containing the time at which the compilation process began.
An integer value. All C++ compilers have this constant defned to some value. Its value depends on
the version of the standard supported by the compiler:
Non conforming compilers defne this constant as some value at most fve digits long. Note that
many compilers are not fully conforming and thus will have this constant defned as neither of the
values above.
1 if the implementation is a hosted implementation (with all standard headers available)
__STDC_HOSTED__
0 otherwise.
The following macros are optionally defned, generally depending on whether a feature is available:
macro value
In C: if defned to 1, the implementation conforms to the C standard.
__STDC__
In C++: Implementation defned.
In C:
http://www.cplusplus.com/doc/tutorial/preprocessor/[03/12/2018 00:57:37]
Preprocessor directives - C++ Tutorials
For example:
Previous: Next:
Exceptions Input/output with fles
Index
http://www.cplusplus.com/doc/tutorial/preprocessor/[03/12/2018 00:57:37]
Input/output with files - C++ Tutorials
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
http://www.cplusplus.com/doc/tutorial/files/[03/12/2018 00:57:58]
Input/output with files - C++ Tutorials
Classes (I)
Classes (II) open (flename, mode);
Special members
Friendship and inheritance Where flename is a string representing the name of the fle to be opened, andmode is an optional parameter with a
combination of the following fags:
Polymorphism
Other language features:
ios::in Open for input operations.
Type conversions
ios::out Open for output operations.
Exceptions
ios::binary Open in binary mode.
Preprocessor directives
Standard library:
Set the initial position at the end of the fle.
ios::ate
If this fag is not set, the initial position is the beginning of the fle.
Input/output with
All output operations are performed at the end of the fle, appending the content to the current content
fles ios::app
of the fle.
If the fle is opened for output operations and it already existed, its previous content is deleted and
ios::trunc
replaced by the new one.
All these fags can be combined using the bitwise operator OR (|). For example, if we want to open the fle
example.bin in binary mode to add data we could do it by the following call to member function open:
1 ofsream myfle;
2 myfle.open ("example.bin", ios::out | ios::app | ios::binary);
Each of the open member functions of classes ofsream, ifsream and fsream has a default mode that is used if the fle
is opened without a second argument:
default mode
class
parameter
ofsream ios::out
ifsream ios::in
fsream ios::in | ios::out
For ifsream and ofsream classes, ios::in and ios::out are automatically and respectively assumed, even if a mode
that does not include them is passed as second argument to the open member function (the fags are combined).
For fsream, the default value is only applied if the function is called without specifying any value for the mode
parameter. If the function is called with any value in that parameter the default mode is overridden, not combined.
File streams opened in binary mode perform input and output operations independently of any format considerations.
Non-binary fles are known as text fles, and some translations may occur due to formatting of some special characters
(like newline and carriage return characters).
Since the frst task that is performed on a fle stream is generally to open a fle, these three classes include a
constructor that automatically calls the open member function and has the exact same parameters as this member.
Therefore, we could also have declared the previous myfle object and conduct the same opening operation in our
previous example by writing:
Combining object construction and stream opening in a single statement. Both forms to open a fle are valid and
equivalent.
http://www.cplusplus.com/doc/tutorial/files/[03/12/2018 00:57:58]
Input/output with files - C++ Tutorials
To check if a fle stream was successful opening a fle, you can do it by calling to member is_open. This member
function returns a bool value of true in the case that indeed the stream object is associated with an open fle, orfalse
otherwise:
Closing a fle
When we are fnished with our input and output operations on a fle we shall close it so that the operating system is
notifed and its resources become available again. For that, we call the stream's member function close. This member
function takes fushes the associated bufers and closes the fle:
myfle.close();
Once this member function is called, the stream object can be re-used to open another fle, and the fle is available
again to be opened by other processes.
In case that an object is destroyed while still associated with an open fle, the destructor automatically calls the
member function close.
Text fles
Text fle streams are those where the ios::binary fag is not included in their opening mode. These fles are designed
to store text and thus all values that are input or output from/to them can sufer some formatting transformations,
which do not necessarily correspond to their literal binary value.
Writing operations on text fles are performed in the same way we operated with cout:
Reading from a fle can also be performed in the same way that we did with cin:
http://www.cplusplus.com/doc/tutorial/files/[03/12/2018 00:57:58]
Input/output with files - C++ Tutorials
11 {
12 while ( getline (myfle,line) )
13 {
14 cout << line << '\n';
15 }
16 myfle.close();
17 }
18
19 else cout << "Unable to open fle";
20
21 return 0;
22 }
This last example reads a text fle and prints out its content on the screen. We have created a while loop that reads the
fle line by line, using getline. The value returned by getline is a reference to the stream object itself, which when
evaluated as a boolean expression (as in this while-loop) is true if the stream is ready for more operations, and false
if either the end of the fle has been reached or if some other error occurred.
bad()
Returns true if a reading or writing operation fails. For example, in the case that we try to write to a fle that is
not open for writing or if the device where we try to write has no space left.
fail()
Returns true in the same cases as bad(), but also in the case that a format error happens, like when an
alphabetical character is extracted when we are trying to read an integer number.
eof()
Returns true if a fle open for reading has reached the end.
good()
It is the most generic state fag: it returns false in the same cases in which calling any of the previous functions
would return true. Note that good and bad are not exact opposites (good checks more state fags at once).
The member function clear() can be used to reset the state fags.
ifsream, like isream, keeps an internal get position with the location of the element to be read in the next input
operation.
ofsream, like osream, keeps an internal put position with the location where the next element has to be written.
Finally, fsream, keeps both, the get and the put position, like iosream.
These internal stream positions point to the locations within the stream where the next reading or writing operation is
performed. These positions can be observed and modifed using the following member functions:
http://www.cplusplus.com/doc/tutorial/files/[03/12/2018 00:57:58]
Input/output with files - C++ Tutorials
These functions allow to change the location of the get and put positions. Both functions are overloaded with two
diferent prototypes. The frst form is:
seekg ( position );
seekp ( position );
Using this prototype, the stream pointer is changed to the absolute position position (counting from the beginning of
the fle). The type for this parameter is sreampos, which is the same type as returned by functions tellg and tellp.
Using this prototype, the get or put position is set to an ofset value relative to some specifc point determined by the
parameter direction. ofset is of type sreamof. And direction is of type seekdir, which is an enumerated type that
determines the point from where ofset is counted from, and that can take any of the following values:
The following example uses the member functions we have just seen to obtain the size of a fle:
Notice the type we have used for variables begin and end:
sreampos size;
sreampos is a specifc type used for bufer and fle positioning and is the type returned byfle.tellg(). Values of this
type can safely be subtracted from other values of the same type, and can also be converted to an integer type large
enough to contain the size of the fle.
These stream positioning functions use two particular types: sreampos and sreamof. These types are also defned as
member types of the stream class:
http://www.cplusplus.com/doc/tutorial/files/[03/12/2018 00:57:58]
Input/output with files - C++ Tutorials
types.
sreamof ios::of_type It is an alias of one of the fundamental integral types (such as int or long long).
Each of the member types above is an alias of its non-member equivalent (they are the exact same type). It does not
matter which one is used. The member types are more generic, because they are the same on all stream objects (even
on streams using exotic types of characters), but the non-member types are widely used in existing code for historical
reasons.
Binary fles
For binary fles, reading and writing data with the extraction and insertion operators (<< and >>) and functions like
getline is not efcient, since we do not need to format any data and data is likely not formatted in lines.
File streams include two member functions specifcally designed to read and write binary data sequentially: write and
read. The frst one (write) is a member function of osream (inherited by ofsream). And read is a member function of
isream (inherited by ifsream). Objects of class fsream have both. Their prototypes are:
Where memory_block is of type char* (pointer to char), and represents the address of an array of bytes where the
read data elements are stored or from where the data elements to be written are taken. The size parameter is an
integer value that specifes the number of characters to be read or written from/to the memory block.
In this example, the entire fle is read and stored in a memory block. Let's examine how this is done:
First, the fle is open with the ios::ate fag, which means that the get pointer will be positioned at the end of the fle.
This way, when we call to member tellg(), we will directly obtain the size of the fle.
Once we have obtained the size of the fle, we request the allocation of a memory block large enough to hold the entire
fle:
http://www.cplusplus.com/doc/tutorial/files/[03/12/2018 00:57:58]
Input/output with files - C++ Tutorials
Right after that, we proceed to set the get position at the beginning of the fle (remember that we opened the fle with
this pointer at the end), then we read the entire fle, and fnally close it:
At this point we could operate with the data obtained from the fle. But our program simply announces that the content
of the fle is in memory and then fnishes.
The operating system may also defne other layers of bufering for reading and writing to fles.
When the bufer is fushed, all the data contained in it is written to the physical medium (if it is an output stream). This
process is called synchronization and takes place under any of the following circumstances:
When the fle is closed: before closing a fle, all bufers that have not yet been fushed are synchronized and
all pending data is written or read to the physical medium.
When the bufer is full: Bufers have a certain size. When the bufer is full it is automatically synchronized.
Explicitly, with manipulators: When certain manipulators are used on streams, an explicit synchronization
takes place. These manipulators are: fush and endl.
Explicitly, with member function sync(): Calling the stream's member function sync() causes an immediate
synchronization. This function returns an int value equal to -1 if the stream has no associated bufer or in case
of failure. Otherwise (if the stream bufer was successfully synchronized) it returns 0.
Previous:
Preprocessor directives
Index
http://www.cplusplus.com/doc/tutorial/files/[03/12/2018 00:57:58]
Privacy policy
This website uses cookies. By continuing, you give permission to deploy cookies, as detailed in our privacy policy. ok
Search: Go
Not logged in
C++
Information
Tutorials
Reference
Articles
Forum
Privacy policy
The privacy of our visitors is important to us. This page represents our commitment on that issue and informs you how
we use personal information collected on this site.
Personal information
The resources hosted in this website are generally provided to visitors anonimously - no personal information is
required to access them.
Nevertheless, some services that allow users to participate actively by submitting content require the user to be
registered. All registered users need to provide at least the following information:
Login name: Your login name is public and will be associated with any content you submit. It serves to identify
you as the author and will appear alongside it.
Email address: Your email address is needed for identifcation purposes. It is only public if you choose so (by
default it is not).
Password: We don't store your password, only a one-way hash value of it.
These felds are kept in our database for identifcation purposes, and are only used for the services provided in this
website and those you opt-in voluntarily.
Registered users have the option to fll a Personal profle with some additional personal information which can be partly
or entirely made public.
Non-personal information
Some non-personal information is automatically logged by our servers as provided by internet protocols and the
browser you use, this includes:
IP addresses
Referer pages
Cookies
Browser information, such as name, version, operating system...
This information is temporarily stored in our servers for statistical and reviewing purposes.
Most browser applications allow you to restrict the disclosure of some or all of the above information. Please check your
browser's manual for more detail.
User-provided content
This site includes sections where users can submit their own content. Any information that is disclosed in these sections
may become public information accessible by other visitors.
Advertisements
Some pages in our site include ads provided by third parties that may use their own technology (such as cookies or web
beacons) to collect user information when they advertise on this site.
External links
This site contains links to other sites. We cannot be responsible for the privacy practices or the content of such web
sites.
We reserve the right to make changes to this policy. Any changes to this policy will be posted.
Home page | Privacy policy
© cplusplus.com, 2000-2017 - All rights reserved - v3.1
Spotted an error? contact us
http://www.cplusplus.com/privacy.do[03/12/2018 00:58:23]