You are on page 1of 96

C++

Fundamentos, POO, Patrones de Diseo


Martinez, Pablo A.
pabloa.mar@gmail.com

Bloques
ANSI/ISO C++ / Fundamentals
POO
librera STL
Patrones de Diseo
UML

C++ online
C++ Shell
http://cpp.sh/

Ideone
http://ideone.com/

To compile source code and execute it online

An online compiler and debugging tool


More than 60 programming languages.

Included options:

Standard
Warnings
Optimization level
Standard Input

Coding ground
http://www.tutorialspoint.com/codingground.
htm

Bloque 1: ANSI/ISO C++

C/C++
Gran acierto de C++
Mantener compatibilidad con C: cualquier programa C podra ser considerado
tambin como un programa C++
Mayor acierto tambin es su defecto ms criticado
Se da origen a hbridos donde no existe un modelo de programacin
predominante (POO, Programacin Procedural)

Rapid Quiz
Q 1 - One of the following is true for an inline
function.

A - It executes faster as it is treated as a macro


internally
B - It executes faster because it priority is more
than normal function
C - It doesnt executes faster compared to a
normal function
D - None of the above holds true for an inline
function

Rapid Quiz
Answer : A
Explanation
As inline function gets expanded at the line of
call like a macro it executes faster.

Rapid Quiz
Q 2 - What is the output of the following program?
#include<iostream>
using namespace std;
class abc {
public:
int i;
abc(int i) {
i = i;
}
};
main() {
abc m(5);
cout<<m.i;
}

A-5
B - Garbage
C - Error at the statement i=i;
D - Compile error: i declared twice.

Rapid Quiz
Answer : B
Explanation
i=i, is assigning parameter to itself.

Rapid Quiz
Q 3 - Runtime polymorphism is done using.

A - Function overloading
B - Virtual classes
C - Virtual functions
D - Friend function

Rapid Quiz
Answer : C
Explanation
Virtual functions gives the ability to override the
functionality of base class into the derived
class. Hence achieving dynamic/runtime
polymorphism.

Rapid Quiz
Q 4 - Which feature of the OOPS gives the
concept of reusability?

A - Abstraction
B - Encapsulation
C - Inheritance
D - None of the above.

Rapid Quiz
Answer : C
Explanation
The process of designing a new class (derived)
from the existing (base) class to acquire the
attributes of the existing is called as inheritance.
Inheritance gives the concept of reusability for
code/software components.

Rapid Quiz
Q 5 - What is the output of the following
program?

#include<iostream>
using namespace std;
void f() {
static int i = 3;
cout<<i;
if(--i) f();
}
main() {
f();
}

Rapid Quiz
Answer : B
Explanation
As the static variable retains its value from the
function calls, the recursion happens thrice.

Rapid Quiz
Q 6 - What is the output of the following
program?

#include<iostream>
using namespace std;
main()
{
int a[] = {10, 20, 30};
cout<<*a+1;
}

Rapid Quiz
Answer : C
Explanation
*a refers to 10 and adding a 1 to it gives 11.

Rapid Quiz
Q 7 - Which operator is required to be
overloaded as member function only?

A-_
B-__
C - ++ (postfix version)
D-=

Rapid Quiz
Answer : D
Explanation
Overloaded assignment operator does the job
similar to copy constructor and is required to be
overloaded as member function of the class.

Rapid Quiz
Q 8 - A protected member of the class in
accessible in

A - Only same class


B - Same class and derived class
C - Outside the class
D - None of the above.

Rapid Quiz
Answer : B
Explanation
Only members of the derived class and the
same class can access a protected member.

Rapid Quiz
Q 9 - What is the output of the following
program?
A-5
B-6
C - Runtime error
D - Compile error

#include<iostream>
using namespace std;
main() {
int const a = 5;
a++;
cout<<a;
}

Rapid Quiz
Answer : D
Explanation
Compile error - constant variable cannot be
modified.

Rapid Quiz
Q 10 - What is the output of the following
program?
A-111
B-000
C-321
D-123

#include<iostream>
using namespace std;
void f() {
static int i;
++i;
cout<<i<< ;
}
main()
{
f();
f();
f();
}

Rapid Quiz
Answer : D
Explanation
1 2 3, A static local variables retains its value
between the function calls and the default value
is 0.

Rapid Quiz
Q 11 - In the following program f() is
overloaded.
A - True
B - False

void f(int x) {
x++;
}
int f(signed x) {
return x;
}
main() {
}

Rapid Quiz
Answer : B
Explanation
No, as both the functions arguments is same
and compiler ignores return type to consider
overloading though different in return type.

Rapid Quiz
Q 12 - What is a generic class.

A - Function template
B - Class template
B - Inherited class
B - None of the above.

Rapid Quiz
Answer : B
Explanation
Defining a templated class is defining a generic
class. Hence functionality of the class is
generalized for several types, if applicable.

Rapid Quiz
Q 13 - What is the output of the following
program?
A-31
B-33
C-11
D-13

#include<iostream>
using namespace std;
class abc {
public:
static int x;
int i;
abc() {
i = ++x;
}
};
int abc::x;
main() {
abc m, n, p;
cout<<m.x<<" "<<m.i<<endl;
}

Rapid Quiz
Answer : A
Explanation
The static member variable x shares common
memory among all the objects created for the
class.

Rapid Quiz
Q 14 - What is the output of the following
program?

#include<iostream>
#include<string.h>

A-59
B - 7 20
C - 5 20
D - 8 20

using namespace std;


main()
{
char s[]="Hello\0Hi";
Cout<<strlen(s)<< <<sizeof(s);
}

Rapid Quiz
Answer : A
Explanation
Length of the string is count of character upto
\0. sizeof reports the size of the array.

Rapid Quiz
Q 15 - What is the output of the following
program?
A - 73 73
B - 60 13
C - 13 60
D - 60 60

#include<isotream>
using namespace std;
main()
{
int i = 13, j = 60;
i^=j;
j^=i;
i^=j;
cout<<i<< <<j;
}

Rapid Quiz
60 13, its swapping.

C++ Fundamentals

Palabras reservadas
C y C++
const double float int short struct unsigned break continue
else for long signed switch void case default enum goto
register sizeof typedef volatile char do extern if return static
union while

Palabras reservadas
C++:
asm

dynamic_cast

new static_cast

typeid

typename class friend


public

throw

namespace reinterpret_cast
catch

false

try bool

operator template

private this using const_cast inline

virtual delete

mutable protected

true wchar_t

explicit

Variables
Regla

ejemplos no vlidos:

Debe comenzar con una letra o un


carcter de guin bajo (underscore)

Debe continuar con una letra, un numero o


un caracter de guion bajo

No debe coincidir con una palabra


reservada

1a
switch
$contador
my var

Enteros
Enteros
[signed | unsigned] [short | long] int
[signed | unsigned] short [int]
[signed | unsigned] long [int]

El lenguaje especifica que un tipo de dato short int debe ser menor o igual en tamao a
un int, el cual deber ser menor o igual a un tipo de dato long int

Enteros
Enteros (Plataforma de 32: 386, 486, Pentium)
Tipo de Dato

Lmites

Memoria

short int

-32.767 a 32.767

2 bytes

unsigned short int

0 a 65.535

2 bytes

int

-2.147.482.647 a 2.147.482.647

4 bytes

unsigned int

0 a 4.294.967.295

4 bytes

long int

-2.147.482.647 a 2.147.482.647

4 bytes

unsigned long int

0 a 4.294.967.295

4 bytes

Enteros
What will the line of code below print out and
why?
cout << 25u - 50;

The answer is not -25.


Rather, the answer (which will surprise many) is
4294967271, assuming 32 bit integers.
Why?

Enteros
If the types of two operands differ from one another:
The operand with the lower type will be promoted to
the type of the higher type operand

Type hierarchy:

So when the two operands are 25u (unsigned int) and 50


(int), the 50 is promoted to also being an unsigned
integer (i.e., 50u).
Moreover, the result of the operation will be of the type
of the operands.

(listed here from highest type to lowest type)


long double, double, float, unsigned long int, long int,
unsigned int, int (lowest).

Therefore, the result of 25u - 50u will itself be an


unsigned integer as well. So the result of -25 converts to
4294967271 when promoted to being an unsigned
integer.

Nmeros No enteros
Nmeros No enteros
Nmero con parte fraccionaria: float (precisin simple) y double (precisin
doble)
Diferencia entre float y double: la precisin
C++ no especifica un tamao concreto pero s establece que la variable del tipo
float debe ser menor o igual en tamao al tipo double, la cual debe ser menor o
igual a la del tipo long double

Nmeros No enteros (formal)


Here is what the standard C99 or C++2003
standards say:
There are three floating point types: float,
double, and long double.

The set of values of the type float is a subset of


the set of values of the type double; the set of
values of the type double is a subset of the set
of values of the type long double.
The C++ standard adds:

The type double provides at least as much


precision as float, and the type long double
provides at least as much precision as double.

The value representation of floating-point types


is implementation-defined.

Nmeros No enteros
Conversin Implcita
Cualquier nmero decimal es tomado como de
precisin doble.
En el ejemplo, cuando realizamos la asignacin,
el mismo es llevado a precisin simple.

Asignaciones a nmeros flotantes en C++


double a = 4.3; //cte numrica decimal doble 4.3 a la
variable a.

float a

= 4.3; //cte numrica decimal doble 4.3 a la

variable a + conversin implcita

float b = 4.3f; //Ahora el compilador sabe que 4.3 es de


precisin simple.

Para evitar esto, aadimos f a la cte literal

Nmeros No enteros
There are other such constructs such as for example
0UL which means a (unsigned long)0, whereas a plain 0
would be an (int)0.
The .f is actually two components:

the . which indicates that the literal is a floating


point number rather than an integer, and
the f suffix which tells the compiler the literal
should be of type float rather than the default
double type used for floating point literals.

float a = 1/3; // (int) / (int) => (int)


float b = 1/3.0; // (int) / (double) +implicit conver => (float)
float c = 1.0/3; // (double) / (int) +implicit conver => (float)
float d = 1.f/3; // (float) / (int) => (float)
float e = 1/3.f; // (int) / (float) => (float)
float f = (float)1/3; // static_cast<float>(int) / (int) => (float)
float g = 1/(float)3; // (int) / static_cast<float>(int) => (float)
std::cout << a << "\n" << b << "\n"<< c << "\n"<< d << "\n"
<< e << "\n" << f << "\n"<< g << "\n";
output
0 0.333333 0.333333 0.333333 0.333333 0.333333 0.333333

Nmeros No enteros
In general a double has 15 to 16 decimal digits
of precision, while float only has 7.

float a = 1.f / 81;


float b = 0;
for (int i = 0; i < 729; ++ i) b += a;
printf("%.7g\n", b);

The maximum value of float is only about 3e38,


but double is about 1.7e308

// prints 9.000023

This precision loss could lead to truncation


errors much easier to float up!

while
double a = 1.0 / 81;
double b = 0;
for (int i = 0; i < 729; ++ i) b += a;
printf("%.15g\n", b);
// prints 8.99999999999996

Nmeros No enteros
No Enteros (Plataforma de 32: 386, 486, Pentium)
Tipo de Dato

Lmites

Memoria

float

10E-38 a 10E38

4 bytes

double

10E-308 a 10E308

8 bytes

long double

10E-308 a 10E308

8 bytes

El tamao de long double


microsoft visual c++ estipula 8 bytes
gcc estipula 12 bytes

sizeof operator
Queries size of the object or type.
Used when actual size of the object must be
known.

C++ language has no such thing as typeof. Its a


GCC compiler-specific extension.
More info:

sizeof( type )
sizeof expression
Both versions return a constant of type std::
size_t

https://gcc.gnu.org/onlinedocs/gcc-5.3.0
/gcc/Typeof.html

sizeof operator
#include <iostream>
struct Empty {};
struct Base { int a; };
struct Derived : Base { int b; };
struct Bit { unsigned bit: 1; };
int main()
{
Empty e;
Derived d;
Base& b = d;
Bit bit;
std::cout << "size of empty class: " << sizeof e
<< '\n'
<< "size of pointer : "
<< sizeof &e
<< '\n'
//
<< "size of function: "
<< sizeof(void()) << '\n' // error
//
<< "size of incomplete type: " << sizeof(int[]) << '\n' // error
//
<< "size of bit field: "
<< sizeof bit.bit << '\n' // error
<< "size of array of 10 int: " << sizeof(int[10]) << '\n'
<< "size of the Derived: " << sizeof d
<< '\n'
<< "size of the Derived through Base: " << sizeof b << '\n';
}

size of empty class: 1


size of pointer : 8
size of array of 10 int: 40
size of the Derived: 8
size of the Derived through Base: 4
The example output corresponds to a system
with 64-bit pointers and 32-bit int.

Operator precedence
Operator precedence and associativity helps in
determining the sequence of applicability of operators
when multiple operators act on a operand in an
expression.

x=2+3%4

Operators are classified into groups.

x = 2 + (3 % 4)

Precedence indicates which operator group applies first


on the operand. Higher precedence are applied first
then operators with lower precedence.

Binary operator + has a higher precedence than operator


=, so it gets evaluated next:

Binary operator % has higher precedence than operator


+ or operator =, so it gets evaluated first:

Final answer: x = (2 + (3 % 4))


The order in which operator of same group are applied is
associativity.

Operator precedence

Operator precedence

Operator precedence
Example:

Exercises:

char * cstar = susan;


char c = *++cstar;

a) x = 3 + 4 + 5;
b) x = y = z;

The unary * and ++ have the same precedence,


and the associativity is from right to left. We
apply ++ first, then *. So c should be u.

c) z *= ++y + 5;
d) a || b && c || d;

Operator precedence
Answers
a) Binary operator + has higher precedence than
=:
x = (3 + 4 + 5);
Binary operator + has left to right association:
Final answer: x = ((3 + 4) + 5);
b) Binary operator = has right to left association:
Final answer: x = (y = z);

c) Unary operator ++ has the highest


precedence:
z *= (++y) + 5;
Binary operator + has the next highest
precedence:
Final answer: z *= ((++y) + 5);
d) Binary operator && has higher precedence
than ||:
a || (b && c) || d;
Binary operator || has left to right association:
Final answer: (a || (b && c)) || d;

switch vs if else
The switch statement is faster to execute than the ifelse-if ladder. This is due to the compiler's ability to
optimise the switch statement.

When creating your own software you are unlikely to see


a real performance problem based upon the choice
between the if statement and the switch command.

if-else-if: the code must process each if statement in


the order determined by the programmer.

Unless you do see a performance problem you should


always choose the option that makes the code more
readable and maintainable.

However, because each case within a switch statement


does not rely on earlier cases, the compiler is able to use
branch tables in such a way as to provide the fastest
execution. All items get the same access time

Speed-test: http://www.blackwasp.co.
uk/SpeedTestIfElseSwitch.aspx

switch vs if else: last opinion


Why do you care?
90% of the time, you shouldn't care.
These sorts of micro-optimizations are unlikely
to affect the performance of your code.
If you NEEDED to care, then you should be doing
performance profiling on your code. In which
case finding out the performance difference
between a switch case and an if-else block
would be trivial.

For clarity's sake:


Implement whichever design is clearer and more
maintainable.
Generally when faced with a huge switch-case
or if-else block the solution is to use
polymorphism: Find the behavior that's
changing and encapsulate it.

switch vs if else: last opinion


You should always care about readability and
maintainability.
Polymorphism is, incidentally, probably slightly
slower, but you shouldn't care.

Macro-optimization (good design) is always


better than micro-optimization (faster
statements)

enum and switch


When enumerations are used in a switch statement,
many compilers issue warnings if one of the
enumerators is not handled
main.cpp:11:7: warning: enumeration value 'BLUE' not
handled in switch [-Wswitch]
switch(a) {
^
main.cpp:11:1: warning: 'a' is used uninitialized in this
function [-Wuninitialized]
switch(a) {

enum color {RED, GREEN, BLUE};


Color a;
switch (a) {
case RED:
std::cout << "red\n";
break;
case GREEN:
std::cout << "green\n";
break;
//case BLUE:
// std::cout << "blue\n";
//break;
}

switch Warning flags


-Wswitch
Warn a switch statement has an index of enumerated type and
lacks a case of the named codes of that enumeration. (The
presence of a default label prevents this warning.) case labels
outside the enumeration range also provoke warnings when this
option is used (even if there is a default label).
This warning is enabled by -Wall.
-Wswitch-default
Warn a switch statement does not have a default case.
-Wswitch-enum
The only difference between -Wswitch and this option is that this
option gives a warning about an omitted enumeration code even if
there is a default label.

Wswitch-bool
Warn a switch statement has an index of boolean type and the case
values are outside the range of a boolean type. It is possible to
suppress this warning by casting the controlling expression to a
type other than bool. For example:
switch ((int) (a == 4))
{
...
}
This warning is enabled by default for C and C++ programs.

Array
Coleccin de elementos de cierto tipo
El nombre de un array es un puntero que
contiene la direccin de memoria del primer
elemento del array
El chequeo de lmites en un array no es
verificado (como en otros lenguajes)

Todos los elementos de un array son colocados


de manera adyacente en la memoria;
acceso fcil y rpido de sus elementos por
medio de un subndice

String en C++

No es un tipo de dato fundamental del lenguaje


Es un tipo de dato derivado
C: Un string es un array de caracteres terminado en \0 (NULL)
C++: utiliza la misma convencin y especifa, ademas, una clase llamada std::string, que
manipula dicho array para que su operatoria sea mas sencilla.
Denominamos cstring a un string tipo C.
Un carcter para el valor NULL: un array de 16 caracteres podra almacenar 15 chars, ya que
deberemos reservar uno para el NULL

cstrings functions
Check header <cstring> (string.h)
C Strings: this header file defines several functions to manipulate C strings and arrays.

Copying, Concatenation, Comparison, Searching, Others

See: http://www.cplusplus.com/reference/cstring/

cstrings functions
Example: copy string
strcpy
char * strcpy ( char * destination, const char * source );
Copies the C string pointed by source into the array
pointed by destination, including the terminating null
character (and stopping at that point).

To avoid overflows, the size of the array pointed by


destination shall be long enough to contain the same C
string as source (including the terminating null
character), and should not overlap in memory with
source.

Functions

Functions
When a program calls a function, program
control is transferred to the called function.
A called function performs defined task
It returns program control back to the main
program when:

its return statement is executed or


its function-ending closing brace is
reached

Functions
La declaracin de una funcin consiste en
especificar su tipo, su identificador, el tipo de
dato de los parmetros que recibe y su tipo de
dato de retorno. (Prototipo de una funcin)

Es conveniente colocar todas las declaraciones


en un archivo distinto de cpp, donde se colocan
las definiciones, header files (.h)
e.g.: #include declaraciones_de_funciones.h

C++ realiza una verificacin esttica de


tipos (cantidad y tipo de parmetros)

Passing arguments
Pass by Value

Copy of arguments passed to function


(once the function is finished, local
variables are destroyed )
Changes in function do not affect original
Use when function does not need to
modify arguments

Example
int doSth(int a, int b, int c);

Pass by Reference

Passes original arguments


Changes in function do affect original
variables

Example
int doSth(int &a, int &b, int &c);

Passing arguments
#include <iostream>
using namespace std;
int divide(int numerator, int denominator, int
&remainder)
{
remainder = numerator % denominator;
return numerator / denominator;
}

int main() {
int num = 14;
int den = 4;
int rem;
int result = divide(num, den, rem);
cout << result << "*" << den << "+" << rem << "="
<< num << endl;
//The print on the screen is: 3*4+2=12
}

Array as parameters
just need to add [ ] to the end of declaration

Example
int doSth(int values[], unsigned len);
To call it:
int len = 10;
int values[len];
doSth(values, len );

Constant Parameters
Constant Parameters

Example

To avoid the content of a parameter is modified,


just prepend const keyword

void tryToModify ( const int values [ ] )


{
values [0] = 10; // compilation error;
}
Output
error: assignment of read-only location '* values'

Reference Arguments (google style)


Pros:

Cons:
Defining a parameter as reference avoids ugly
code like (*pval)++.
Necessary for some applications like copy
constructors.
Makes it clear, unlike with pointers, that a null
pointer is not a possible value.

References can be confusing, as they have value


syntax but pointer semantics.

Reference Arguments (google style)


Within function parameter lists all references
must be const:
void Foo(const string &in, string *out);
input arguments are values or const references
may be const pointers,
but never non-const reference parameters
except when required by convention, e.g.,
swap().
output arguments are pointers

However, there are some instances where using


const T* is preferable to const T& for input
parameters.
For example:
You want to pass in a null pointer.
The function saves a pointer or reference
to the input.
Read more: https://google.github.
io/styleguide/cppguide.
html#Reference_Arguments

Default Values for Parameters


You can specify a default value for each of the last
parameters
If a value for that parameter is not passed when the
function is called, the default given value is used (if a
value is specified, this default value is ignored)
All subsequent parameters must have a default
argument supplied in this or a previous declaration.

The ellipsis is not a parameter, and so can follow a


parameter with a default argument.

int f(int = 1, int); // error, assuming there's no previous


declaration of f int f(int , int=1);

int g(int n = 0, ...); // ok


template<class...T>
void h(int i = 0, T... args); // ok
more on ellipsis:
http://www.learncpp.com/cpp-tutorial/714-ellipsis-andwhy-to-avoid-them/

Default Values for Parameters


The names used in the default arguments are
looked up, checked for accessibility, and bound
at the point of declaration, but are executed at
the point of the function call

int a = 1;
int f (int);
int g (int x = f(a)); // lookup for f finds ::f, lookup for a
finds ::a // the value of ::a, which is 1 at this point, is not
used
void h()
{
a = 2; // changes the value of ::a
{
int a = 3;
g();
// calls f(2), then calls g() with the result
}
}

Default Values for Parameters


Non-static class members are not allowed in default
arguments (even if they are not evaluated)
except when used to:

form a pointer-to-member or
in a member access expression.

class X
{
int a;
static int b;
int mem1(int i = a); // error: non-static member cannot
be used
int mem2(int i = b); // OK: lookup finds X::b, the static
member
};

Default Values for Parameters


For a member function, the default arguments are
allowed on the out-of-class definition, and are combined
with the default arguments provided by the declaration
inside the class body.
If these out-of-class defaults would turn a member
function into a default, copy, or move constructor the
program is ill-formed.
For member functions of class templates, all defaults
must be provided in the initial declaration of the
member function.

class C {
void f(int i = 3);
void g(int i, int j = 99);
C(int arg); // non-default constructor
};
//out-of-class definition (eg: c.cpp)
void C::f(int i = 3) {
// error: default argument already
}
// specified in class scope
void C::g(int i = 88, int j) { // OK: in this translation unit,
}
// C::g can be called with no argument
C::C(int arg = 1) { // error: turns this into a default constructor
}

Inline Functions
Calling a function generally causes a certain
overhead (stacking arguments, jumps, etc...),
and thus for very short functions, it may be more
efficient to simply insert the code of the
function where it is called.
Preceding a function declaration with the inline
specifier suggest the compiler that inline
expansion is preferred.
Code generated by the function body shall be
inserted at each point the function is called

For example, the concatenate function above


may be declared inline as:
inline string concatenate (const string& a, const
string& b)
{
return a+b;
}
more:
https://isocpp.org/wiki/faq/inline-functions#inlinemember-fns

User defined
types

Structures
A data structure is a group of data elements,
known as members, grouped together under one
name.
It is a user-defined type
In the case where object_names are specified,
the type name (product) becomes optional:
struct requires either atype_name or at least one
name in object_names, but not necessarily both.

struct type_name {
type1 name1;
type2 name2;
type3 name3;
} object_names; // optional
struct product {
int weight;
double price;
};
product apple;
product lime, coconut;

Structure Initialization
We can initialize a struct object with braces.
(.) es el member access operator
Example:
struct Automovil_t {
int
id;
unsigned kms;
bool
abs;
};
Automovil_t auto = {1, 0, true};

Expre
ssion

What is evaluated

Equiv
alent

a.b

Member b of object a

a->b

Member b of object pointed to by a

(*a).b

*a.b

Value pointed to by member b of


object a

*(a.b)

typedef
typedef is a keyword. This is used to define a
new name for an existing data type. The general
form is:
typedef datatype newname;
In C++ there is no need to specify the keyword
typedef for enum, structure and union data
types. (like C)

Compared with Macros:


typedef defines a new type, in terms of existing
types.
Macros are simply text replacements.

typedef
// simple typedef
typedef unsigned long ulong;

// the following two objects have the same type


pS ps1;
S* ps2;

// the following two objects have the same type


unsigned long l1;
ulong l2;

// error: storage-class-specifier cannot appear in a typedef


declaration
// typedef static unsigned int uint;

// more complicated typedef


typedef int int_t, *intp_t, (&fp)(int, ulong), arr_t[10];

// std::add_const, like many other metafunctions, use member


typedefs
template< class T>
struct add_const {
typedef const T type;
};

// the following two objects have the same type


int a1[10];
arr_t a2;
// common C idiom to avoid having to write "struct S"
typedef struct {int a; int b;} S, *pS;

typedef struct Node {


struct listNode* next; // declares a new (incomplete) struct type
named listNode
} listNode; // error: conflicts with the previously declared struct name

Unions
A union is a special class type that can hold only
one of its non-static data members at a time.

The class specifier for a union declaration is


similar to class or struct declaration:

union class-head-name { member-specification }

Just like in struct declaration, the default


member access in a union is public.

A union can have member functions


(including constructors and destructors),
but not virtual functions.
A union cannot have base classes and
cannot be used as a base class.
A union cannot have data members of
reference types.

Unions
The union is only as big as necessary to hold its
largest data member.
The other data members are allocated in the
same bytes as part of that largest member.
The details of that allocation are
implementation-defined, and it's undefined
behavior to read from the member of the union
that wasn't most recently written.

Unions

Unions, example 1
#include <iostream>
union S
{
std::int32_t n; // 4 bytes
std::uint16_t s[2]; // 4 bytes
std::uint8_t c; // 1 byte
};
// the whole union occupies 4 bytes

int main()
{
S s = {0x12345678}; // initializes the first member, s.n is now the active
member
// at this point, reading from s.s or s.c is undefined behavior (UB)
std::cout << std::hex << "s.n = " << s.n << '\n';
s.s[0] = 0x0011; // s.s is now the active member
// at this point, reading from n or c is UB but most compilers define it
std::cout << "s.c is now " << +s.c << '\n' // 11 or 00, depending on platform
<< "s.n is now " << s.n << '\n'; // 12340011 or 00115678
}
more: http://en.cppreference.com/w/cpp/language/union

Unions, example 2
#include <iostream>
#include <stdio.h>
using namespace std;

size_t size = ftell(f);


// file size in bytes
fseek(f, 0, SEEK_SET);
size /= 4;
// file size in 32bit ints

union u_color {
// first representation (member of union)
struct s_color {
unsigned char a, b, g, r;
} uc_color;
// second representation (member of union)
unsigned int i_color;
};

Union most likely will cause cross-CPU


(endianess) problems with you application.
This is irrelevant if you write programs only
for x86 processors

for(size_t i=0; i<size; i++)


{
u_color clr;
//reading from tile to clr.i_color
fread(&clr.i_color, sizeof(unsigned int), 1, f);
// printing from clr.uc_color to output stream
cout << "R=" << int(clr.uc_color.r) << " ";
cout << "G=" << int(clr.uc_color.g) << " ";
cout << "B=" << int(clr.uc_color.b) << " ";
cout << "A=" << int(clr.uc_color.a) << endl;
}
fclose(f);

int main(void) {
FILE *f = fopen("color.dat", "rb");
if (f == NULL)
exit(1);
fseek(f, 0, SEEK_END);
}

Enumerated types (enum)


Enumerated types are types that are defined
with a set of custom identifiers, known as
enumerators, as possible values. Objects of
these enumerated types can take any of these
enumerators as value.

Example
enum colors_t {black, blue, green, cyan, red,
purple, yellow, white};
colors_t mycolor;

enum type_name {
value1,
value2,
...
} object_names;

mycolor = blue;
if (mycolor == green) mycolor = red;

Enumerated types (enum)


Values of enum are implicitly convertible to the
integer type int, and vice versa. In fact, the
elements of such an enum are always assigned
an integer numerical equivalent internally, of
which they become an alias. If it is not specified
otherwise, the integer is 0, the equivalent to the
second is 1, to the third is 2, and so on...
Therefore, in the data type colors_t defined
above, black would be equivalent to 0, blue
would be equivalent to 1, green to 2, and so on...

enum months {
january = 1,
febrary = 2,
march = 3,

july = 7;
jy = 7; // same value for other option
}

Enum
Setting initial values

enum Months {
january = 1,
february, //2
march,
april,
may,
june,
july,
jl= 7,
august, //8
september,
october,
november,
december
}

Enum
Enums are distinct types, so you can do typeoriented things like overloading with them:

enum Color { Red, Green, Blue };


enum Size { Big, Little };
void f ( Color c ) {
}
void f ( Size s ) {
}
int main() {
f( Red );
f( Big );
}

Enum
I like the automatic behavior that can be used
with enums, for example:
Then it is easy to loop until LAST, and when a
new state (or whatever is represented) is added,
the logic adapts.

enum {NONE, START, HEY, HO, LAST};


for (int i = NONE; i < LAST; i++)
{
// Do stuff...
}
enum {NONE, START, HEY, WEE, HO, LAST};
The loop adapts...

Enumerated types with enum class (c++11)


In C++, it is possible to create real enum types that are
neither implicitly convertible to int and that neither have
enumerator values of type int, but of the enum type
itself, thus preserving type safety.
They are declared with enum class (or enum struct)
instead of just enum

enum class Colors {black, blue, green, cyan, red, purple,


yellow, white};
Colors mycolor;
mycolor = Colors::blue;
if (mycolor == Colors::green) mycolor = Colors::red;
enum class EyeColor : char {blue, green, brown};

Each of the enumerator values of an enum class type


needs to be scoped into its type (this is actually also
possible with num types, but it is only optional)

Here, Eyecolor is a distinct type with the same size of a


char (1 byte).

Version

Versin
v1.2.

Comentario
Versin para curso de C++
CASA, tarde.

Fecha
20/03/2016

Autor
Martnez, Pablo

You might also like