
Samsung Research Tijuana
Memoria estática (Stack)
Los objetos en memoria estática son destruidos automáticamente al finalizar el bloque donde fueron declarados.
Memoria dinámica (Heap)
Los objetos en memoria dinámica continúan con vida hasta que sean destruidos explícitamente, esto permite que salgan del bloque en el que fueron declarados.
#include <iostream>
int c = 1; /* Global */
int main()
{
int a = 1; /* Bloque */
int b = 1;
{
int a = 1; /* Segunda declaración de 'a' oculta la primera declaración. */
std::cout << a++ << std::endl; /* 1 */
b += a;
c = 3;
}
++a;
++c;
std::cout << a << std::endl; /* 2 */
std::cout << b << std::endl; /* 3 */
std::cout << c << std::endl; /* 4 */
}Declaración
La sintaxis para declarar una variable apuntador es:
T *nombre= valor;
Donde:
T: El tipo del dato al que se apunta.
nombre: El nombre de la variable apuntador.
valor: El valor inicial del apuntador (opcional).
int *intPointer = nullptr;Operadores
Operador * (Indirección)
Regresa una referencia al contenido del apuntador.
*intPointer = 5;
int number = *intPointer;Operador -> (Acceso a miembro)
Acceso al miembro de una clase o estructura contenida por un apuntador. Exactamente igual a utilizar "(*T).<miembro de T>"
std::string *name = getName();
int nameLenght = name->size();Operadores
Operador & (Dirección de)
Regresa la dirección de memoria del objeto al cual se le aplique el operador en forma de un apuntador.
std::string name = "Victor";
std::string *namePtr = &name;Operadores
Operador new
Este operador crea un nuevo objeto en memoria dinámica y regresa un apuntador al objeto creado.
double *doublePointer = new double(10.0);Operador delete
Destruye un objeto en memoria dinámica y libera el espacio de memoria que el objeto ocupaba.
delete doublePointer;int main()
{
int i = 5; /* Objeto en memoria estática. */
int *ptr1; /* Apuntador no inicializado. */
int *ptr2 = nullptr; /* Apuntador nulo. */
int *ptr3 = &i; /* Apuntador a la dirección de i. */
int *ptr4 = new int(10); /* Apuntador a un espacio de memoria dinámica. */
std::string *name = getName();
*ptr1 = name->size(); /* Error: Acceso de memoria invalido */
*ptr2 = name->size(); /* Error: ptr1 es nulo */
*ptr3 = name->size(); /* Ok, modifica el valor de i */
*ptr4 = name->size(); /* Ok, modifica el valor del objeto en memoria dinámica. */
delete ptr4; /* Objetos en memoria dinámica se borran explícitamente. */
delete name;
return 0;
}#include <string>
class Cellphone
{
public:
Cellphone(std::string brand)
: mBrand(brand)
{}
std::string brand() const
{
return mBrand;
}
private:
std::string mBrand;
};
#include <iostream>
#include "Cellphone.h"
Cellphone* badPhoneFactory(std::string brand)
{
Cellphone p(brand);
return &p;
}
Cellphone* phoneFactory(std::string brand)
{
Cellphone *p = new Cellphone(brand);
return p;
}
int main()
{
Cellphone *samsung = phoneFactory("Samsung");
Cellphone *apple = badPhoneFactory("Apple");
std::cout << samsung->brand() << std::endl;
std::cout << apple->brand() << std::endl; /* Error */
delete samsung;
delete apple;
}Cellphone.h
main.cpp
RAII (Resource Acquisition Is Initialization)
Un objeto debe reservar sus recursos durante la inicialización (Constructor) y liberarlos durante su destrucción (Destructor).
class XmlParser
{
public:
XmlParser(const std::string &xmlFilePath)
: xmlFile(new File(xmlFilePath)),
contents(new ByteArray())
{
if (xmlFile->open(File::ReadOnly))
{
contents = xmlFile->readAllBytes();
}
}
~XmlParser()
{
if (xmlFile != nullptr && xmlFile->isOpen())
{
xmlFile->close();
}
delete xmlFile;
delete contents;
}
XmlObject parse() { /* Hacer algo con el contenido. */ }
private:
File *xmlFile;
ByteArray *contents;
}class XmlParser
{
public:
XmlParser(const std::string &xmlFilePath)
: xmlFile(new File(xmlFilePath)),
contents(new ByteArray())
{
if (xmlFile->open(File::ReadOnly))
{
contents = xmlFile->readAllBytes();
}
}
~XmlParser()
{
if (xmlFile->isOpen())
{
xmlFile->close();
}
delete xmlFile;
delete contents;
}
XmlObject parse() { /* Hacer algo con el contenido. Puede causar excepción. */ }
private:
File *xmlFile;
ByteArray *contents;
}template <typename T>
class PointerWrapper
{
public:
PointerWrapper(T *pointer)
: pointer(pointer)
{}
~PointerWrapper()
{
delete pointer;
}
T& operator*()
{
return *pointer;
}
T* operator->() { /* Implementacion */ }
T& operator=() { /* Implementacion */ }
private:
T *pointer;
}class XmlParser
{
public:
XmlParser(const std::string &xmlFilePath)
: xmlFile(new File(xmlFilePath)),
contents(new ByteArray())
{
if (xmlFile->open(File::ReadOnly))
{
contents = xmlFile->readAllBytes();
}
}
~XmlParser()
{
if (xmlFile->isOpen())
{
xmlFile->close();
}
}
XmlObject parse() { /* Hacer algo con el contenido. Puede causar excepción. */ }
private:
PointerWrapper<File> xmlFile;
PointerWrapper<ByteArray> contents;
}Un smart pointer es un contenedor para un apuntador regular que se encarga de eliminar automáticamente el objeto dinámico y liberar la memoria ocupada por el apuntador. Este tipo de apuntadores fueron introducidos en C++11.
Es un apuntador que tiene el control del objeto al que apunta, cuando se destruye la instancia de std::unique_ptr también se destruye el objeto al que apunta. Por lo tanto solo puede haber una sola instancia apuntando al mismo objeto.
void parseXml(const std::string &xmlFilePath)
{
XmlParser *parser = getParser();
try
{
parser->parse();
delete parser;
}
catch (Exception &e)
{
std::cout << e.what();
delete parser;
}
}void parseXml(const std::string &xmlFilePath)
{
std::unique_ptr<XmlParser> parser(getParser());
try
{
parser->parse();
}
catch (Exception &e)
{
std::cout << e.what();
}
}Este apuntador mantiene un conteo de instancias, el objeto en memoria dinámica se destruye cuando el conteo de instancias llega a cero. Por lo tanto es posible tener muchas instancias de std::shared_ptr apuntando al mismo espacio de memoria.
#include <string>
class Cellphone
{
public:
Cellphone(std::string brand)
: mBrand(brand)
{}
std::string brand() const
{
return mBrand;
}
private:
std::string mBrand;
};
#include <iostream>
#include <memory>
#include "Cellphone.h"
std::shared_ptr<Cellphone> phoneFactory(std::string brand)
{
std::shared_ptr<Cellphone> p =
make_shared<Cellphone>(brand);
return p;
}
int main()
{
auto samsung = phoneFactory("Samsung");
std::cout << samsung->brand() << std::endl;
}Cellphone.h
main.cpp