Vous êtes sur la page 1sur 14

Arrays - C++ Tutorials

Search:
Go

Tutorials

C++ Language

Arrays

Not logged in

register

log in

C++
Information
Tutorials
Reference
Articles
Forum

You are using a version without Ads of this website. Please, consider donating:

[hide]

Tutorials
C++ Language
Ascii Codes
Boolean Operations
Numerical Bases

C++ Language
Introduction:
Compilers
Basics of C++:
Structure of a program
Variables and types
Constants
Operators
Basic Input/Output
Program structure:
Statements and flow control
Functions
Overloads and templates
Name visibility
Compound data types:
Arrays
Character sequences
Pointers
Dynamic memory
Data structures
Other data types
Classes:
Classes (I)
Classes (II)
Special members
Friendship and inheritance
Polymorphism
Other language features:
Type conversions
Exceptions
Preprocessor directives
Standard library:
Input/output with files

C++

Free Answers to Your C++


Language Questions. Register Now!

Arrays

An array is a series of elements of the same type placed in contiguous memory locations that can be individually
referenced by adding an index to a unique identifier.

That means that, for example, five values of type int can be declared as an array without having to declare 5 different
variables (each with its own identifier). Instead, using an array, the five int values are stored in contiguous memory
locations, and all five can be accessed using the same identifier, with the proper index.

For example, an array containing 5 integer values of type int called foo could be represented as:

where each blank panel represents an element of the array. In this case, these are values of type int. These elements
are numbered from 0 to 4, being 0 the first and 4 the last; In C++, the first element in an array is always numbered
with a zero (not a one), no matter its length.

Like a regular variable, an array must be declared before it is used. A typical declaration for an array in C++ is:

type name [elements];

where type is a valid type (such as int, float...), name is a valid identifier and the elements field (which is always
enclosed in square brackets []), specifies the length of the array in terms of the number of elements.

Therefore, the foo array, with five elements of type int, can be declared as:
int foo [5];

NOTE: The elements field within square brackets [], representing the number of elements in the array, must be a
constant expression, since arrays are blocks of static memory whose size must be determined at compile time, before
the program runs.

Initializing arrays

By default, regular arrays of local scope (for example, those declared within a function) are left uninitialized. This
means that none of its elements are set to any particular value; their contents are undetermined at the point the array
is declared.

But the elements in an array can be explicitly initialized to specific values when it is declared, by enclosing those initial
values in braces {}. For example:
int foo [5] = { 16, 2, 77, 40, 12071 };

This statement declares an array that can be represented like this:

http://www.cplusplus.com/doc/tutorial/arrays/[12/19/2014 10:28:50 AM]

Arrays - C++ Tutorials

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 specified 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 filled with zeroes). For example:
int bar [5] = { 10, 20, 30 };

Will create an array like this:

The initializer can even have no values, just the braces:

int baz [5] = { };

This creates an array of five 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 {}:
int foo [] = { 16, 2, 77, 40, 12071 };

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:
1 int foo[] = { 10, 20, 30 };
2 int foo[] { 10, 20, 30 };

Static arrays, and those declared directly in a namespace (outside any function), are always initialized. If no explicit
initializer is specified, all the elements are default-initialized (with zeroes, for fundamental types).

Accessing the values of an array

The values of any of the elements in an array can be accessed just like the value of a regular variable of the same
type. The syntax is:
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:
foo [2] = 75;
http://www.cplusplus.com/doc/tutorial/arrays/[12/19/2014 10:28:50 AM]

Arrays - C++ Tutorials

and, for example, the following copies the value of the third element of foo to a variable called x:
x = foo[2];

Therefore, the expression foo[2] is itself a variable of type int.

Notice that the third element of foo is specified foo[2], since the first 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 different 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.
1 int foo[5];
2 foo[2] = 75;

// declaration of a new array


// access to an element of the array.

The main difference is that the declaration is preceded by the type of the elements, while the access is not.

Some other valid operations with arrays:


1
2
3
4

foo[0] = a;
foo[a] = 75;
b = foo [a+2];
foo[foo[a]] = foo[2] + 5;

For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

// arrays example
#include <iostream>
using namespace std;

12206

int foo [] = {16, 2, 77, 40, 12071};


int n, result=0;
int main ()
{
for ( n=0 ; n<5 ; ++n )
{
result += foo[n];
}
cout << result;
return 0;
}

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];
http://www.cplusplus.com/doc/tutorial/arrays/[12/19/2014 10:28:50 AM]

Arrays - C++ Tutorials

and, for example, the way to reference the second element vertically and fourth horizontally in an expression would
be:
jimmy[1][3]

(remember that array indices always begin with zero).

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 [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:
1 int jimmy [3][5];
2 int jimmy [15];

// is equivalent to
// (3 * 5 = 15)

With the only difference 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:
multidimensional array

pseudo-multidimensional array

#define WIDTH 5
#define HEIGHT 3

#define WIDTH 5
#define HEIGHT 3

int jimmy [HEIGHT][WIDTH];


int n,m;

int jimmy [HEIGHT * WIDTH];


int n,m;

int main ()
int main ()
{
{
for (n=0; n<HEIGHT; n++)
for (n=0; n<HEIGHT; n++)
for (m=0; m<WIDTH; m++)
for (m=0; m<WIDTH; m++)
{
{
jimmy[n*WIDTH+m]=(n+1)*(m+1);
jimmy[n][m]=(n+1)*(m+1);
}
}
}
}

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 defined 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.
http://www.cplusplus.com/doc/tutorial/arrays/[12/19/2014 10:28:50 AM]

Arrays - C++ Tutorials

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 effect, and it is a much faster and more efficient 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:
void procedure (int arg[])

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];

it would be enough to write a call like this:


procedure (myarray);

Here you have a complete example:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

// arrays as parameters
#include <iostream>
using namespace std;

5 10 15
2 4 6 8 10

void printarray (int arg[], int length) {


for (int n=0; n<length; ++n)
cout << arg[n] << ' ';
cout << '\n';
}
int main ()
{
int firstarray[] = {5, 10, 15};
int secondarray[] = {2, 4, 6, 8, 10};
printarray (firstarray,3);
printarray (secondarray,5);
}

In the code above, the first 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 first 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]

For example, a function with a multidimensional array as argument could be:


void procedure (int myarray[][3][4])

Notice that the first 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.

http://www.cplusplus.com/doc/tutorial/arrays/[12/19/2014 10:28:50 AM]

Arrays - C++ Tutorials

Library arrays

The arrays explained above are directly implemented as a language feature, inherited from the C language. They are a
great feature, but by restricting its copy and easily decay into pointers, they probably suffer 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) defined 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. Suffice 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:
language built-in array
#include <iostream>
using namespace std;

container library array


#include <iostream>
#include <array>
using namespace std;

int main()
int main()
{
{
array<int,3> myarray {10,20,30};
int myarray[3] = {10,20,30};
for (int i=0; i<myarray.size(); ++i)
++myarray[i];

for (int i=0; i<3; ++i)


++myarray[i];

for (int elem : myarray)


cout << elem << '\n';

for (int elem : myarray)


cout << elem << '\n';
}

As you can see, both kinds of arrays use the same syntax to access its elements: myarray[i]. Other than that, the
main differences 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:
Name visibility

Index

Next:
Character sequences

MLton SML compiler


Whole-program, high performance compiler for Standard ML.
Home page | Privacy policy
cplusplus.com, 2000-2014 - All rights reserved - v3.1
Spotted an error? contact us

http://www.cplusplus.com/doc/tutorial/arrays/[12/19/2014 10:28:50 AM]

Classes (II) - C++ Tutorials

Search:
Go

Tutorials

C++ Language

Not logged in

Classes

register

log in

C++
Information
Tutorials
Reference
Articles
Forum

Tutorials
C++ Language
Ascii Codes
Boolean Operations
Numerical Bases

C++ Language
Introduction:
Compilers
Basics of C++:
Structure of a program
Variables and types
Constants
Operators
Basic Input/Output
Program structure:
Statements and flow control
Functions
Overloads and templates
Name visibility
Compound data types:
Arrays
Character sequences
Pointers
Dynamic memory
Data structures
Other data types
Classes:
Classes (I)
Classes (II)
Special members
Friendship and inheritance
Polymorphism
Other language features:
Type conversions
Exceptions
Preprocessor directives
Standard library:
Input/output with files

Brain Training Games


Challenge memory and attention
with scientific brain games.

Classes (II)
Overloading operators

Classes, essentially, define new types to be used in C++ code. And types in C++ not only interact with code by means
of constructions and assignments. They also interact by means of operators. For example, take the following operation
on fundamental types:
1 int a, b, c;
2 a = b + c;

Here, different variables of a fundamental type (int) are applied the addition operator, and then the assignment
operator. For a fundamental arithmetic type, the meaning of such operations is generally obvious and unambiguous,
but it may not be so for certain class types. For example:
1 struct myclass {
2
string product;
3
float price;
4 } a, b, c;
5 a = b + c;

Here, it is not obvious what the result of the addition operation on b and c does. In fact, this code alone would cause a
compilation error, since the type myclass has no defined behavior for additions. However, C++ allows most operators
to be overloaded so that their behavior can be defined for just about any type, including classes. Here is a list of all the
operators that can be overloaded:
Overloadable operators
+
<<= >>=
~
&=
delete

*
/
==
!=
^=
|=
new[]

=
<
<=
>=
&&
||
delete[]

>
++
%=

+=
-[]

-=
%
()

*=
&
,

/=
^
->*

<<
!
->

>>
|
new

Operators are overloaded by means of operator functions, which are regular functions with special names: their name
begins by the operator keyword followed by the operator sign that is overloaded. The syntax is:
type operator sign (parameters) { /*... body ...*/ }

For example, cartesian vectors are sets of two coordinates: x and y. The addition operation of two cartesian vectors is
defined as the addition both x coordinates together, and both y coordinates together. For example, adding the
cartesian vectors (3,1) and (1,2) together would result in (3+1,1+2) = (4,3). This could be implemented in C++
with the following code:
1
2
3
4
5
6
7
8
9
10
11
12

// overloading operators example


#include <iostream>
using namespace std;
class CVector {
public:
int x,y;
CVector () {};
CVector (int a,int b) : x(a), y(b) {}
CVector operator + (const CVector&);
};

http://www.cplusplus.com/doc/tutorial/templates/[12/19/2014 10:57:11 AM]

4,3

Classes (II) - C++ Tutorials


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

CVector CVector::operator+ (const CVector&


param) {
CVector temp;
temp.x = x + param.x;
temp.y = y + param.y;
return temp;
}
int main () {
CVector foo (3,1);
CVector bar (1,2);
CVector result;
result = foo + bar;
cout << result.x << ',' << result.y << '\n';
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:
1 CVector (int, int) : x(a), y(b) {} // function name CVector (constructor)
2 CVector operator+ (const CVector&); // function that returns a CVector

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);

Both expressions are equivalent.

In an earlier chapter, the copy assignment function was introduced as one of the special member functions that are
implicitly defined, even when not explicitly declared in the class. The behavior of this function by default is to copy the
whole content of the data members of the object passed as argument (the one at the right side of the sign) to the one
at the left side:
1 CVector d (2,3);
2 CVector e;
3 e = d;
// copy assignment operator

The copy assignment member is the only operator implicitly defined for all classes. Of course, it can be redefined to
any other functionality, such as, for example, to copy only certain members or perform additional initialization
operations.

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 fill 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 different operators than can be overloaded (please, replace @ by the operator in
each case):
Expression
Operator
Member function
@a
+ - * & ! ~ ++ -A::operator@()
a@
++ -A::operator@(int)
a@b
+ - * / % ^ & | < > == != <= >= << >> && || , A::operator@(B)
a@b
= += -= *= /= %= ^= &= |= <<= >>= []
A::operator@(B)
a(b,c...) ()
A::operator()(B,C...)
a->b
->
A::operator->()
(TYPE) a
TYPE
A::operator TYPE()
http://www.cplusplus.com/doc/tutorial/templates/[12/19/2014 10:57:11 AM]

Non-member function
operator@(A)
operator@(A,int)
operator@(A,B)
-

Classes (II) - C++ Tutorials

Where a is an object of class A, b is an object of class B and c is an object of class C. TYPE is just any type (that
operators overloads the conversion to type TYPE).

Notice that some operators may be overloaded in two forms: either as a member function or as a non-member
function: The first 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 first
argument.

For
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

example:
// non-member operator overloads
#include <iostream>
using namespace std;

4,3

class CVector {
public:
int x,y;
CVector () {}
CVector (int a, int b) : x(a), y(b) {}
};
CVector operator+ (const CVector& lhs, const
CVector& rhs) {
CVector temp;
temp.x = lhs.x + rhs.x;
temp.y = lhs.y + rhs.y;
return temp;
}
int main () {
CVector foo (3,1);
CVector bar (1,2);
CVector result;
result = foo + bar;
cout << result.x << ',' << result.y << '\n';
return 0;
}

The keyword this

The keyword this represents a pointer to the object whose member function is being executed. It is used within a
class's member function to refer to the object itself.

One of its uses can be to check if a parameter passed to a member function is the object itself. For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

// example on this
#include <iostream>
using namespace std;

yes, &a is b

class Dummy {
public:
bool isitme (Dummy& param);
};
bool Dummy::isitme (Dummy& param)
{
if (&param == this) return true;
else return false;
}
int main () {
Dummy a;
Dummy* b = &a;
if ( b->isitme(a) )
cout << "yes, &a is b\n";
return 0;
}

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 defined as:
1 CVector& CVector::operator= (const CVector& param)
2 {
3
x=param.x;
4
y=param.y;
5
return *this;
6 }
http://www.cplusplus.com/doc/tutorial/templates/[12/19/2014 10:57:11 AM]

Classes (II) - C++ Tutorials

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 different 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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

// static members in classes


#include <iostream>
using namespace std;

7
6

class Dummy {
public:
static int n;
Dummy () { n++; };
~Dummy () { n--; };
};
int Dummy::n=0;
int main () {
Dummy a;
Dummy b[5];
Dummy * c = new Dummy;
cout << a.n << '\n';
delete c;
cout << Dummy::n << '\n';
return 0;
}

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;

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):
1 cout << a.n;
2 cout << Dummy::n;

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.

Const member functions

When an object of a class is qualified as a const object:


const MyClass myobject;

http://www.cplusplus.com/doc/tutorial/templates/[12/19/2014 10:57:11 AM]

Classes (II) - C++ Tutorials

The access to its data members from outside the class is restricted to read-only, as if all its data members were const
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

// constructor on const object


#include <iostream>
using namespace std;

10

class MyClass {
public:
int x;
MyClass(int val) : x(val) {}
int get() {return x;}
};
int main() {
const MyClass foo(10);
// foo.x = 20;
cannot be modified
cout << foo.x << '\n';
can be read
return 0;
}

// not valid: x
// ok: data member x

The member functions of a const object can only be called if they are themselves specified as const members; in the
example above, member get (which is not specified as const) cannot be called from foo. To specify that a member is
a const member, the const keyword shall follow the function prototype, after the closing parenthesis for its
parameters:
int get() const {return x;}

Note that const can be used to qualify the type returned by a member function. This const is not the same as the one
which specifies a member as const. Both are independent and are located at different places in the function prototype:
1 int get() const {return x;}
// const member function
2 const int& get() {return x;}
// member function returning a const&
3 const int& get() const {return x;} // const member function returning a const&

Member functions specified to be const cannot modify non-static data members nor call other non-const member
functions. In essence, const members shall not modify the state of an object.
const objects are limited to access only members marked as const, but non-const objects are not restricted and thus
can access both const and non-const members alike.

You may think that anyway you are seldom going to declare const objects, and thus marking all members that don't
modify the object as const is not worth the effort, but const objects are actually very common. Most functions taking
classes as parameters actually take them by const reference, and thus, these functions can only access their const
members:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

// const objects
#include <iostream>
using namespace std;

10

class MyClass {
int x;
public:
MyClass(int val) : x(val) {}
const int& get() const {return x;}
};
void print (const MyClass& arg) {
cout << arg.get() << '\n';
}
int main() {
MyClass foo (10);
print(foo);
return 0;
}

If in this example, get was not specified as a const member, the call to arg.get() in the print function would not be
http://www.cplusplus.com/doc/tutorial/templates/[12/19/2014 10:57:11 AM]

Classes (II) - C++ Tutorials


possible, because const objects only have access to const 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 const and the other is not: in this case, the const version is called only when the object
is itself const, and the non-const version is called when the object is itself non-const.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

// overloading members on constness


#include <iostream>
using namespace std;

15
20

class MyClass {
int x;
public:
MyClass(int val) : x(val) {}
const int& get() const {return x;}
int& get() {return x;}
};
int main() {
MyClass foo (10);
const MyClass bar (20);
foo.get() = 15;
// ok: get() returns
int&
// bar.get() = 25;
// not valid: get()
returns const int&
cout << foo.get() << '\n';
cout << bar.get() << '\n';
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:
1 template <class T>
2 class mypair {
3
T values [2];
4
public:
5
mypair (T first, T second)
6
{
7
values[0]=first; values[1]=second;
8
}
9 };

The class that we have just defined 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:
mypair<int> myobject (115, 36);

This same class could also be used to create an object to store any other type, such as:
mypair<double> myfloats (3.0, 2.18);

The constructor is the only member function in the previous class template and it has been defined inline within the
class definition itself. In case that a member function is defined outside the defintion of the class template, it shall be
preceded with the template <...> prefix:
1
2
3
4
5
6
7
8
9
10
11
12
13
14

// class templates
#include <iostream>
using namespace std;
template <class T>
class mypair {
T a, b;
public:
mypair (T first, T second)
{a=first; b=second;}
T getmax ();
};

http://www.cplusplus.com/doc/tutorial/templates/[12/19/2014 10:57:11 AM]

100

Classes (II) - C++ Tutorials


15
16
17
18
19
20
21
22
23
24
25
26

template <class T>


T mypair<T>::getmax ()
{
T retval;
retval = a>b? a : b;
return retval;
}
int main () {
mypair <int> myobject (100, 75);
cout << myobject.getmax();
return 0;
}

Notice the syntax of the definition of member function getmax:


1 template <class T>
2 T mypair<T>::getmax ()

Confused by so many T's? There are three T's in this declaration: The first 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 specifies that this function's template parameter is also the class template parameter.

Template specialization

It is possible to define a different implementation for a template when a specific 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 find that when it stores
an element of type char it would be more convenient to have a completely different implementation with a function
member uppercase, so we decide to declare a class template specialization for that type:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

// template specialization
#include <iostream>
using namespace std;

8
J

// class template:
template <class T>
class mycontainer {
T element;
public:
mycontainer (T arg) {element=arg;}
T increase () {return ++element;}
};
// class template specialization:
template <>
class mycontainer <char> {
char element;
public:
mycontainer (char arg) {element=arg;}
char uppercase ()
{
if ((element>='a')&&(element<='z'))
element+='A'-'a';
return element;
}
};
int main () {
mycontainer<int> myint (7);
mycontainer<char> mychar ('j');
cout << myint.increase() << endl;
cout << mychar.uppercase() << endl;
return 0;
}

This is the syntax used for the class template specialization:


template <> class mycontainer <char> { ... };

First of all, notice that we precede the class name with template<> , including an empty parameter list. This is
http://www.cplusplus.com/doc/tutorial/templates/[12/19/2014 10:57:11 AM]

Classes (II) - C++ Tutorials


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 prefix, is the <char> specialization parameter after the class template name. This
specialization parameter itself identifies the type for which the template class is being specialized (char). Notice the
differences between the generic class template and the specialization:
1 template <class T> class mycontainer { ... };
2 template <> class mycontainer <char> { ... };

The first line is the generic template, and the second one is the specialization.

When we declare specializations for a template class, we must also define 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:
Classes (I)

Index

Next:
Special members

Control Valves
Providing Productivity, Efficiency And Accurate Control!
Home page | Privacy policy
cplusplus.com, 2000-2014 - All rights reserved - v3.1
Spotted an error? contact us

http://www.cplusplus.com/doc/tutorial/templates/[12/19/2014 10:57:11 AM]

Vous aimerez peut-être aussi