https://rentry.org/PPP2_p329

// Code derived from Stroustrup's PPP2 book
// § 9.7.3 Default constructors
//  -and beginning on p 329

#include <iostream>
#include <stdexcept>
#include <vector>

using namespace std;

void error(const char* s) { throw runtime_error(s); }

enum class Month {
  jan = 1,
  feb,
  mar,
  apr,
  may,
  jun,
  jul,
  aug,
  sep,
  oct,
  nov,
  dec
};

//------------------------------------------------------------------------------

class Date;                  // pair of fwd decls (used in Date's default ctor)
const Date& default_date();  //

//------------------------------------------------------------------------------

// Instead of placing the default values for members in the constructor, we
// could place them on the [private] members themselves
class Date {
 public:
  Date();  // default constructor
  Date(int year, Month month, int day);
  Date(int y);  // January 1 of year y

  class Invalid {};  // to be used as a Date exception

  // . . .

  int   year() const { return y; }
  Month month() const { return m; }
  int   day() const { return d; }

  friend ostream& operator<<(ostream& os, const Date& d)
  {
    return os << '{' << d.y << ',' << int(d.m) << ',' << d.d << '}';
  }

 private:
  bool is_valid();  // return true if date is valid

  int   y{2001};
  Month m{Month::jan};
  int   d{1};
};

// given default_date(), it is trivial to define a default constructor for Date
Date::Date()
    : y{default_date().year()},
      m{default_date().month()},
      d{default_date().day()}
{
}

Date::Date(int year, Month month, int day) : y{year}, m{month}, d{day} {}

// January 1 of year yy
Date::Date(int yy) : y{yy}
{
  if (! is_valid())
    throw Invalid{};  // check for validity
}

// return true if date is valid
bool Date::is_valid()
{
  if (int(m) < 1 || 12 < int(m))
    return false;

  // ...

  return true;  // naive
}

//------------------------------------------------------------------------------

// The first day of the 21st century (value is already checked, by definition)
const Date& default_date()
{
  static Date dd{2001, Month::jan, 1};
  return dd;
}

int main()
{
  // ten elements with the default Date value, Date{} (the default constructor)
  vector<Date> birthdays(10);

  for (auto& birthday : birthdays)
    cout << birthday << '\n';

  {
    // Without the default constructor, we would have had to be explicit

    vector<Date> birthdays(10, default_date());  // ten default Dates

    // ten default Dates
    vector<Date> birthdays2 = {default_date(), default_date(), default_date(),
                               default_date(), default_date(), default_date(),
                               default_date(), default_date(), default_date(),
                               default_date()};
  }
}

build & run:

g++ -std=c++20 -O2 -Wall -pedantic ./ch_09/main_p329.cpp && ./a.out

PrevUpNext

Edit
Pub: 06 Apr 2023 17:52 UTC
Edit: 03 May 2023 01:21 UTC
Views: 443