Destruction order (C++)

The variables/fields getting cleanup in the reverse order they have been declared (not initialized).


#include <string>
#include <vector>
#include <memory>
#include <iostream>

class Text {
public:
  Text(std::string text) : m_text(text) {}
  ~Text() { std::cout << "Destruct Text '" + toStr() + "'" << std::endl; }
  std::string toStr() { return m_text; }
private:
  std::string m_text;
};

class Number {
public:
  Number(unsigned number) : m_number(number) {}
  ~Number() { std::cout << "Destruct Number '" + toStr() + "'" << std::endl; }
  std::string toStr() { return std::to_string(m_number); }
private:
  unsigned m_number;
};

class Track {
public:
  Track(Text title, Number duration)
    : m_title(title), m_duration(duration) {}
  virtual ~Track() {
    std::cout << "Destruct Track '"
              + m_title.toStr() + "', '" + m_duration.toStr() + "'"
              << std::endl;
  }
protected:
  Text m_title;
  Number m_duration;
};

class CloudTrack : public Track {
public:
  CloudTrack(Text title, Number duration, Text service, Text uuid)
    : Track(title, duration), m_service(service), m_uuid(uuid) {}
  ~CloudTrack() {
    std::cout << "Destruct CloudTrack '"
              + m_title.toStr() + "', '" + m_duration.toStr() + "', '"
              + m_service.toStr() + "', '" + m_uuid.toStr() + "'"
              << std::endl;
  }
private:
  Text m_service;
  Text m_uuid;
};

class TrackVector {
public:
  ~TrackVector() { std::cout << "Destruct TrackVector" << std::endl; }
  void push_back(std::unique_ptr<Track> track) {
    m_vector.push_back(std::move(track));
  }
private:
  std::vector<std::unique_ptr<Track>> m_vector;
};

class Album {
public:
  Album(Text title, Text artist) : m_title(title), m_artist(artist) {}
  ~Album() { std::cout << "Destruct Album '"
                       + m_title.toStr() + "', '" + m_artist.toStr() + "'"
                       << std::endl; }
  void addTrack(std::unique_ptr<Track> track) {
    m_tracks.push_back(std::move(track));
  }
private:
  Text m_title;
  Text m_artist;
  TrackVector m_tracks;
};

int main()
{
  Album album(Text("Trash"), Text("Alice Cooper"));

  album.addTrack(std::make_unique<CloudTrack>(Text("Poison"), Number(270),
    Text("Spotify"), Text("5XcZRgJv3zMhTqCyESjQrF?si=d915382bc9954b34")));
  album.addTrack(std::make_unique<CloudTrack>(Text("Trash"), Number(243),
    Text("Spotify"), Text("69FKPvGvSKIqHxGLDYApYH?si=105d56c3b64b41bb")));

  std::cout << "Objects are created" << std::endl;

  return 0;
}
...
Objects are created
# Cleanup fields of album (Last declared variable in main)
Destruct Album 'Trash', 'Alice Cooper'

## Cleanup album.m_tracks (Last declared field of Album)
Destruct TrackVector

## Cleanup album.m_track[0]
### Cleanup CloudTrack fields
Destruct CloudTrack 'Poison', '270', 'Spotify', '5XcZRgJv3zMh #...
#### Cleanup album.tracks[0].m_service (Last declared field of CloudTrack)
Destruct Text '5XcZRgJv3zMhTqCyESjQrF?si=d915382bc9954b34'
#### Cleanup album.tracks[0].m_uuid (First declared field of CloudTrack)
Destruct Text 'Spotify'
### Cleanup Track fields
Destruct Track 'Poison', '270'
#### Cleanup album.tracks[0].m_duration (Last declared field of Track)
Destruct Number '270'
#### Cleanup album.tracks[0].m_title (First declared field of Track)
Destruct Text 'Poison'

## Cleanup album.m_track[1]
### Cleanup CloudTrack fields
Destruct CloudTrack 'Trash', '243', 'Spotify', '69FKPvGvSKIq #...
#### Cleanup album.tracks[1].m_service (Last declared field of CloudTrack)
Destruct Text '69FKPvGvSKIqHxGLDYApYH?si=105d56c3b64b41bb'
#### Cleanup album.tracks[1].m_uuid (First declared field of CloudTrack)
Destruct Text 'Spotify'
### Cleanup Track fields
Destruct Track 'Trash', '243'
#### Cleanup album.tracks[1].m_duration (Last declared field of Track)
Destruct Number '243'
#### Cleanup album.tracks[1].m_title (First declared field of Track)
Destruct Text 'Trash'

## Cleanup album.m_artist (Midway declared field of Album)
Destruct Text 'Alice Cooper'

## Cleanup album.m_title (First declared field of Album)
Destruct Text 'Trash'

Disclaimer: Keep in mind that if you have explicitly requested space on the heap you have to free/delete it by your own.