Y por qué no usas shared_ptr o unique_ptr??
Si tienes claro que la vida de 's' siempre va a ser superior a los nodos del grafo puedes usar unique_ptr. Si la vida de los objetos pasa a ser más difusa entonces es más recomendable usar shared_ptr:
Ejemplo para unique_ptr:
Código C++:
Ver originalvector<std::unique_ptr<SuperNode>> s(n);
for( auto& node : s )
node = std::make_unique<SuperNode>();
// make_unique<> es un template que crea un unique_ptr ya inicializado
// make_unique<SuperNode>() es equivalente a
// std::unique_ptr<SuperNode>(new SuperNode);
// make_unique también admite parámetros:
// make_unique<SuperNode>(1) es equivalente a
// std::unique_ptr<SuperNode>(new SuperNode(1));
Y para que los nodos apunten al puntero:
Código C++:
Ver originalclass Node
{
SuperNode* superNode;
};
node->superNode = s[0].get();
Opción con shared_ptr (1):
Código C++:
Ver originalvector<std::shared_ptr<SuperNode>> s(n);
for( auto& node : s )
node = std::make_shared<SuperNode>();
Y para referenciar el puntero:
Código C++:
Ver originalclass Node
{
std::weak_ptr<SuperNode> superNode;
};
node->superNode = s[0]; // La conversión a weak es implícita
¿Por qué usar weak? shared_ptr es una clase que gestiona un puntero que va a utilizarse en varias secciones del código. Lo que hace shared_ptr es mantener vivo el puntero mientras existan referencias al mismo (una referencia = una instancia de shared_ptr referenciando al puntero). Cuando ya no hay elementos shared_ptr referenciando el puntero la memoria es liberada de forma automática.
Si resulta que tienes una referencia circular (A referencia a B y B a A), entonces la memoria nunca se liberaría porque ambos punteros tendrían siempre una referencia.... en estos casos es donde entra en acción weak_ptr. weak_ptr representa una referencia débil a un puntero compartido. Es debil porque no impide que el puntero sea destruído (no cuenta como referencia). Para evitar problemas el propio weak_ptr incluye funcionalidad que indica si el puntero está vivo o no.
Un ejemplo ilustrativo:
Código C++:
Ver originalvoid CrearShared(std::weak_ptr<int> weakPtr)
{
if( std::shared_ptr<int> miShared = weakPtr.lock() )
{
std::cout << "El puntero esta referenciado " << weakPtr.use_count() << " vece(s)\n";
std::cout << "shared_ptr = " << *miShared << '\n';
}
else
{
std::cout << "El puntero ha sido eliminado\n";
}
}
int main()
{
std::weak_ptr<int> weak;
{
std::shared_ptr<int> shared = std::make_shared<int>(4);
weak = shared;
std::cout << "El puntero esta referenciado " << weak.use_count() << " vece(s)\n";
auto shared2 = shared;
std::cout << "El puntero esta referenciado " << weak.use_count() << " vece(s)\n";
// Si el puntero está vivo podremos usarlo
CrearShared(weak);
// Este mensaje muestra como el número de referencias ha bajado porque el shared_ptr
// que creamos dentro de la función ya no existe
std::cout << "El puntero esta referenciado " << weak.use_count() << " vece(s)\n";
} // En este punto los dos shared_ptr serán eliminados, eso da lugar a que el puntero
// se elimine
// Cuando ya no exista el puntero, weak_ptr nos avisará
CrearShared(weak);
}
Un saludo