Configurare libxml e libxslt in visual studio

La configurazione dei pacchetti open source in visual studio si realizza con vcpkg.

L’installazione di vcpkg si fa accedendo alla pagina
GitHub – microsoft/vcpkg: C++ Library Manager for Windows, Linux, and MacOS · GitHub
e seguendo le istruzioni.

In particolare si deve fare il clone del progetto github:
git clone https://github.com/microsoft/vcpkg.git

Poi si esegue il bat:
cd vcpkg; .\bootstrap-vcpkg.bat

Ora si può installare il pacchetto libxml, seguendo le istruzioni a questa pagina:
python – is there any way to install libxml2 on windows? – Stack Overflow

In particolare:
vcpkg install libxml2:x64-windows
vcpkg install libxslt:x64-windows
vcpkg integrate install

La nuova versione di libxml è libxml2 e gli include da usare si trovano nel direttorio libxml2, quindi visual studio di default non li troverà.
Per fare in modo che li trovi è necessario aggiungere manualmente al progetto il direttorio dove andare a cercare gli include.

Tasto destro sul progetto -> Properties.
In C/C++ -> Direttorio inclusioni aggiuntive, aggiungi:
C:\path\to\vcpkg\installed\x64-windows\include\libxml2

Eventualmente aggiungere anche il linker: Linker -> Direttorio librerie aggiuntive, aggiungi:
C:\path\to\vcpkg\installed\x64-windows\lib

Eventualmente aggiungere anche la dipendenza. Linker -> Input -> Dipendenze addizionali, aggiungi:
libxml2.lib

C++ creare un array di oggetti usando std::vector

Creare array di oggetti in c++ crea sempre qualche problema nella gestione della memoria e nella chiamata ai costruttori.

Infatti una definizione del tipo

Oggetto array[100];

creerà un array di puntatori a 100 oggetti del tipo Oggetto richiamando per ciascuno di essi il costruttore senza parametri. Questo non è sempre corretto. Un’alternativa sarebbe definire l’array come array di puntatori, come di seguito:

Oggetto *array[100]

Questa istruzione creerà un array di puntatori a aree di memoria non inizializzate con nessun oggetto. Con un ciclo si dovranno poi costruire gli oggetti a uno a uno.

Questo schema prevede una gestione della memoria manuale, con il rischio di leak di memoria.

Le nuove specifiche richiedono di utilizzare i contenitori standard, in particolare std::vector. Questo contenitore richiede un po’ di gestione in più, con i relativi costruttori di copie e gli operatori move.

Ovviamente si potrà usare un’istruzione del tipo:

std::vector<Oggetto> array;

creando poi i vari oggetti a uno a uno. In alternativa si può usare un contenitore di puntatori, facendo attenzione che siano puntatori smart.

Suggerimenti per evitare in modo sicuro perdite di memoria

Piuttosto che utilizzare un std::vector di puntatori nudi, utilizzare una raccolta di oggetti std::unique_ptr:
//THIS CREATES VECTOR
std::vector<std::unique_ptr<combustion_car>> combustion_car_list;

  1. Creare l’oggetto temporaneo utilizzando una chiamata a std::make_unique e trasferirne la proprietà al contenitore utilizzando std::move:
    //THIS IS CREATING AND PUSHING THE OBJECT
    std::unique_ptr<combustion_car> temporary=std::make_unique<combustion_car>(); temporary->create();
    combustion_car_list.push_back(std::move(temporary));
    std::cout<<"Object added"<<std::endl;
  2. Rimuovere l’elemento in combustion_car_list[choice] (choice-1 non è corretto, ma anche pericoloso perché potrebbe produrre un valore dell’iteratore che è precedente )
    combustion_car_list.begin();
    //THIS DELETES OBJECT FROM VECTOR combustion_car_list.erase(combustion_car_list.begin() + choice);