Source: http://jczeus.com/refac_cpp.html from "Refactoring; Improving the Design of Existing Code by Martin Fowler


The VideoStore.cpp was created so you have a working example
that can be tested.

Refactoring Example:

  VideoStove.cpp - main routine that works in .NET C++
  Movie.h Movie.cpp
  Rental.h Rental.cpp
  Customer.h Customer.cpp

// VideoStore.cpp : Defines the entry point for the console application.
#include "Customer.h"
#include "Movie.h"
#include "Rental.h"
#include 
  using std::endl;
  using std::cout;

int main(int argc, char* argv[])
{
	Customer bob("Robert Andrews");

	Movie bambi("Bambi", Movie::CHILDRENS);
	Movie lucas("Star Wars", Movie::NEW_RELEASE);
	Movie classic("The African Queen", Movie::REGULAR);

	Rental weekend( lucas, 2);
	Rental week( bambi, 5);
	Rental overnight( classic, 1);

	bob.addRental( weekend );
	bob.addRental( week );
	bob.addRental( overnight );

	cout << bob.statement() << endl;

	return 0;
}


// Movie.h
#ifndef MOVIE_H
#define MOVIE_H
#include 

class Movie {
public:
  static const int CHILDRENS   = 2;
  static const int REGULAR     = 0;
  static const int NEW_RELEASE = 1;

  Movie( const std::string& title, int priceCode = REGULAR );

  int getPriceCode() const;
  void setPriceCode( int arg );
  std::string getTitle() const;

private:
  std::string _title;
  int _priceCode;
};

inline Movie::
Movie( const std::string& title, int priceCode )
  : _title( title )
  , _priceCode( priceCode )
{}

inline int Movie::
getPriceCode() const { return _priceCode; }

inline void Movie::
setPriceCode( int arg ) { _priceCode = arg; }

inline std::string Movie::
getTitle() const { return _title; }

#endif // MOVIE_H


// Movie.cpp
#include "Movie.h"


// Rental.h
#ifndef RENTAL_H
#define RENTAL_H
#include "Movie.h"

class Rental {
public:
  Rental( const Movie& movie, int daysRented );

  int getDaysRented() const;
  Movie & getMovie();

private:
  Movie _movie;
  int _daysRented;
};

inline Rental::
Rental( const Movie& movie, int daysRented )
  : _movie( movie )
  , _daysRented( daysRented ) {}

inline int Rental::
getDaysRented() const { return _daysRented; }

inline Movie & Rental::getMovie() { 
	return _movie; 
}

#endif // RENTAL_H


// Rental.cpp


// Customer.h
#ifndef CUSTOMER_H
#define CUSTOMER_H
#include 
#include 
#include "Rental.h"

class Customer {
public:
  Customer();
  explicit Customer( const std::string& name );

  void addRental( const Rental& arg );
  std::string getName() const;
  std::string statement();

private:
  std::string _name;
  std::vector< Rental > _rentals;
};

inline Customer::Customer() {}

inline Customer::Customer( const std::string& name )
  : _name( name ) {}

inline void Customer::addRental( const Rental& arg ) { 
	_rentals.push_back( arg ); 
}

inline std::string Customer::
getName() const { return _name; }

#endif // CUSTOMER_H


// Customer.cpp
#include 
#include 
#include "Customer.h"

using namespace std;
// using std::ostringstream;
// using std::vector;

string Customer::statement() {
  double totalAmount = 0;
  int frequentRenterPoints = 0;
  vector< Rental >::iterator iter = _rentals.begin();
  vector< Rental >::iterator iter_end = _rentals.end();
  ostringstream result;

  result << "Rental Record for " << getName() << "\n";
  for ( ; iter != iter_end; ++iter ) {
    double thisAmount = 0;
    Rental each = *iter;

    // determine amounts for each line
    switch ( each.getMovie().getPriceCode() ) {
      case Movie::REGULAR:
        thisAmount += 2;
        if ( each.getDaysRented() > 2 )
          thisAmount += ( each.getDaysRented() - 2 ) * 1.5 ;
        break;
      case Movie::NEW_RELEASE:
        thisAmount += each.getDaysRented() * 3;
        break;
      case Movie::CHILDRENS:
        thisAmount += 1.5;
        if ( each.getDaysRented() > 3 )
          thisAmount += ( each.getDaysRented() - 3 ) * 1.5;
        break;
    }

    // add frequent renter points
    frequentRenterPoints++;
    // add bonus for a two day new release rental
    if ( ( each.getMovie().getPriceCode() == Movie::NEW_RELEASE )
         && each.getDaysRented() > 1 ) frequentRenterPoints++;

    // show figures for this rental
    result << "\t" << each.getMovie().getTitle() << "\t"
           << thisAmount << "\n";
    totalAmount += thisAmount;
  }
  // add footer lines
  result << "Amount owed is " << totalAmount << "\n";
  result << "You earned " << frequentRenterPoints
         << " frequent renter points";
  return result.str();
}