#include <iostream>
#include <string>

class Verbose
{
public:
    friend std::ostream& operator<<(std::ostream& os, const Verbose& v) ;

    Verbose() : _id(_nextID++)
        { std::cout << *this << " constructed via default constructor.\n" ; }

    Verbose(const std::string& s) : _id(_nextID++), _data(s)
        { std::cout << *this << " constructed via std::string constructor.\n" ; }

    Verbose( const Verbose& v ) : _id(_nextID++), _data(v._data)
        { std::cout << *this << " constructed via copy constructor from " << v << ".\n" ; }

    ~Verbose()
    {
        std::cout << *this << " destroyed.\n" ;
    }

    Verbose operator=(const Verbose& v)
    {
        std::cout << *this << " = " << v << '\n' ;

        _data = v._data ;

        return *this ;
    }

private:

    const unsigned _id ;
    std::string _data ;

    static unsigned _nextID ;
};

std::ostream& operator<<(std::ostream& os, const Verbose& v )
{
    return os << "Verbose #" << v._id << " (\"" << v._data << "\")" ;
}

unsigned Verbose::_nextID = 1 ;

int main()
{
  Verbose motto1("The devil takes care of his own");    // Verbose #1
  Verbose motto2;                                       // Verbose #2
  Verbose motto3;                                       // Verbose #3

  std::cout << "---- Before temporary expression ----\n" ;
  (motto1 = motto2) = motto3 ;                          // Verbose #4 and #5 are temporaries.
  std::cout << "---- After temporary expression  ----\n" ;

  return 0;
}