This example uses the CompositeInstrument class to perform static replication of a down-and-out barrier option.
#include <ql/qldefines.hpp>
#ifdef BOOST_MSVC
#  include <ql/auto_link.hpp>
#endif
#include <ql/instruments/compositeinstrument.hpp>
#include <ql/instruments/barrieroption.hpp>
#include <ql/instruments/europeanoption.hpp>
#include <ql/pricingengines/barrier/analyticbarrierengine.hpp>
#include <ql/pricingengines/vanilla/analyticeuropeanengine.hpp>
#include <ql/exercise.hpp>
#include <ql/termstructures/yield/flatforward.hpp>
#include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
#include <ql/quotes/simplequote.hpp>
#include <ql/time/calendars/nullcalendar.hpp>
#include <boost/timer.hpp>
#include <iostream>
#include <iomanip>
#if defined(QL_ENABLE_SESSIONS)
}
#endif
int main(int, char* []) {
    try {
        boost::timer timer;
        std::cout << std::endl;
        Date today(29, May, 2006);
         
        Barrier::Type barrierType = Barrier::DownOut;
        Option::Type type = Option::Put;
        Real underlyingValue = 100.0;
         boost::shared_ptr<SimpleQuote> underlying(
        boost::shared_ptr<SimpleQuote> riskFreeRate(
new SimpleQuote(0.04));
        Date maturity = today + 1*Years;
         std::cout << std::endl ;
        
        Size widths[] = { 45, 15, 15 };
         Size totalWidth = widths[0]+widths[1]+widths[2];
         std::string rule(totalWidth, '-'), dblrule(totalWidth, '=');
        std::cout << dblrule << std::endl;
        std::cout << "Initial market conditions" << std::endl;
        std::cout << dblrule << std::endl;
        std::cout << std::setw(widths[0]) << std::left << "Option"
                  << std::setw(widths[1]) << std::left << "NPV"
                  << std::setw(widths[2]) << std::left << "Error"
                  << std::endl;
        std::cout << rule << std::endl;
        
            boost::shared_ptr<YieldTermStructure>(
                                                  h1, dayCounter)));
            boost::shared_ptr<BlackVolTermStructure>(
                                                    h2, dayCounter)));
        
        boost::shared_ptr<Exercise> exercise(
        boost::shared_ptr<StrikedTypePayoff> payoff(
        boost::shared_ptr<BlackScholesProcess> bsProcess(
                                                    flatRate, flatVol));
        boost::shared_ptr<PricingEngine> barrierEngine(
        boost::shared_ptr<PricingEngine> europeanEngine(
                                      payoff, exercise);
        referenceOption.setPricingEngine(barrierEngine);
        Real referenceValue = referenceOption.NPV();
         std::cout << std::setw(widths[0]) << std::left
                  << "Original barrier option"
                  << std::fixed
                  << std::setw(widths[1]) << std::left << referenceValue
                  << std::setw(widths[2]) << std::left << "N/A"
                  << std::endl;
        
        
        
        boost::shared_ptr<Instrument> put1(
        put1->setPricingEngine(europeanEngine);
        
        boost::shared_ptr<StrikedTypePayoff> digitalPayoff(
        boost::shared_ptr<Instrument> digitalPut(
        digitalPut->setPricingEngine(europeanEngine);
        portfolio1.
subtract(digitalPut, strike-barrier);
        portfolio2.
subtract(digitalPut, strike-barrier);
        portfolio3.
subtract(digitalPut, strike-barrier);
        
        boost::shared_ptr<StrikedTypePayoff> lowerPayoff(
        boost::shared_ptr<Instrument> put2(
        put2->setPricingEngine(europeanEngine);
        
        
        
        for (i=12; i>=1; i--) {
            
            Date innerMaturity = today + i*Months;
             boost::shared_ptr<Exercise> innerExercise(
            boost::shared_ptr<StrikedTypePayoff> innerPayoff(
            boost::shared_ptr<Instrument> putn(
            putn->setPricingEngine(europeanEngine);
            
            
            Date killDate = today + (i-1)*Months;
             underlying->setValue(barrier);
            Real portfolioValue = portfolio1.
NPV();
             Real putValue = putn->NPV();
             
            
            Real notional = portfolioValue/putValue;
             
            
        }
        
        underlying->setValue(underlyingValue);
        
        Real portfolioValue = portfolio1.
NPV();
         Real error = portfolioValue - referenceValue;
         std::cout << std::setw(widths[0]) << std::left
                  << "Replicating portfolio (12 dates)"
                  << std::fixed
                  << std::setw(widths[1]) << std::left << portfolioValue
                  << std::setw(widths[2]) << std::left << error
                  << std::endl;
        
        
        for (i=52; i>=2; i-=2) {
            
            Date innerMaturity = today + i*Weeks;
             boost::shared_ptr<Exercise> innerExercise(
            boost::shared_ptr<StrikedTypePayoff> innerPayoff(
            boost::shared_ptr<Instrument> putn(
            putn->setPricingEngine(europeanEngine);
            Date killDate = today + (i-2)*Weeks;
             underlying->setValue(barrier);
            Real portfolioValue = portfolio2.
NPV();
             Real putValue = putn->NPV();
             Real notional = portfolioValue/putValue;
         }
        underlying->setValue(underlyingValue);
        portfolioValue = portfolio2.
NPV();
        error = portfolioValue - referenceValue;
        std::cout << std::setw(widths[0]) << std::left
                  << "Replicating portfolio (26 dates)"
                  << std::fixed
                  << std::setw(widths[1]) << std::left << portfolioValue
                  << std::setw(widths[2]) << std::left << error
                  << std::endl;
        
        
        for (i=52; i>=1; i--) {
            
            Date innerMaturity = today + i*Weeks;
             boost::shared_ptr<Exercise> innerExercise(
            boost::shared_ptr<StrikedTypePayoff> innerPayoff(
            boost::shared_ptr<Instrument> putn(
            putn->setPricingEngine(europeanEngine);
            Date killDate = today + (i-1)*Weeks;
             underlying->setValue(barrier);
            Real portfolioValue = portfolio3.
NPV();
             Real putValue = putn->NPV();
             Real notional = portfolioValue/putValue;
         }
        underlying->setValue(underlyingValue);
        portfolioValue = portfolio3.
NPV();
        error = portfolioValue - referenceValue;
        std::cout << std::setw(widths[0]) << std::left
                  << "Replicating portfolio (52 dates)"
                  << std::fixed
                  << std::setw(widths[1]) << std::left << portfolioValue
                  << std::setw(widths[2]) << std::left << error
                  << std::endl;
        
        
        
        std::cout << dblrule << std::endl;
        std::cout << "Modified market conditions: out of the money"
                  << std::endl;
        std::cout << dblrule << std::endl;
        std::cout << std::setw(widths[0]) << std::left << "Option"
                  << std::setw(widths[1]) << std::left << "NPV"
                  << std::setw(widths[2]) << std::left << "Error"
                  << std::endl;
        std::cout << rule << std::endl;
        underlying->setValue(110.0);
        referenceValue = referenceOption.NPV();
        std::cout << std::setw(widths[0]) << std::left
                  << "Original barrier option"
                  << std::fixed
                  << std::setw(widths[1]) << std::left << referenceValue
                  << std::setw(widths[2]) << std::left << "N/A"
                  << std::endl;
        portfolioValue = portfolio1.
NPV();
        error = portfolioValue - referenceValue;
        std::cout << std::setw(widths[0]) << std::left
                  << "Replicating portfolio (12 dates)"
                  << std::fixed
                  << std::setw(widths[1]) << std::left << portfolioValue
                  << std::setw(widths[2]) << std::left << error
                  << std::endl;
        portfolioValue = portfolio2.
NPV();
        error = portfolioValue - referenceValue;
        std::cout << std::setw(widths[0]) << std::left
                  << "Replicating portfolio (26 dates)"
                  << std::fixed
                  << std::setw(widths[1]) << std::left << portfolioValue
                  << std::setw(widths[2]) << std::left << error
                  << std::endl;
        portfolioValue = portfolio3.
NPV();
        error = portfolioValue - referenceValue;
        std::cout << std::setw(widths[0]) << std::left
                  << "Replicating portfolio (52 dates)"
                  << std::fixed
                  << std::setw(widths[1]) << std::left << portfolioValue
                  << std::setw(widths[2]) << std::left << error
                  << std::endl;
        
        
        std::cout << dblrule << std::endl;
        std::cout << "Modified market conditions: in the money" << std::endl;
        std::cout << dblrule << std::endl;
        std::cout << std::setw(widths[0]) << std::left << "Option"
                  << std::setw(widths[1]) << std::left << "NPV"
                  << std::setw(widths[2]) << std::left << "Error"
                  << std::endl;
        std::cout << rule << std::endl;
        underlying->setValue(90.0);
        referenceValue = referenceOption.NPV();
        std::cout << std::setw(widths[0]) << std::left
                  << "Original barrier option"
                  << std::fixed
                  << std::setw(widths[1]) << std::left << referenceValue
                  << std::setw(widths[2]) << std::left << "N/A"
                  << std::endl;
        portfolioValue = portfolio1.
NPV();
        error = portfolioValue - referenceValue;
        std::cout << std::setw(widths[0]) << std::left
                  << "Replicating portfolio (12 dates)"
                  << std::fixed
                  << std::setw(widths[1]) << std::left << portfolioValue
                  << std::setw(widths[2]) << std::left << error
                  << std::endl;
        portfolioValue = portfolio2.
NPV();
        error = portfolioValue - referenceValue;
        std::cout << std::setw(widths[0]) << std::left
                  << "Replicating portfolio (26 dates)"
                  << std::fixed
                  << std::setw(widths[1]) << std::left << portfolioValue
                  << std::setw(widths[2]) << std::left << error
                  << std::endl;
        portfolioValue = portfolio3.
NPV();
        error = portfolioValue - referenceValue;
        std::cout << std::setw(widths[0]) << std::left
                  << "Replicating portfolio (52 dates)"
                  << std::fixed
                  << std::setw(widths[1]) << std::left << portfolioValue
                  << std::setw(widths[2]) << std::left << error
                  << std::endl;
        
        
        std::cout << dblrule << std::endl;
        std::cout
            << std::endl
            << "The replication seems to be less robust when volatility and \n"
            << "risk-free rate are changed. Feel free to experiment with \n"
            << "the example and contribute a patch if you spot any errors."
            << std::endl;
        double seconds = timer.elapsed();
        seconds -= hours * 3600;
        seconds -= minutes * 60;
        std::cout << " \nRun completed in ";
        if (hours > 0)
            std::cout << hours << " h ";
        if (hours > 0 || minutes > 0)
            std::cout << minutes << " m ";
        std::cout << std::fixed << std::setprecision(0)
                  << seconds << " s\n" << std::endl;
        return 0;
    } catch (std::exception& e) {
        std::cerr << e.what() << std::endl;
        return 1;
    } catch (...) {
        std::cerr << "unknown error" << std::endl;
        return 1;
    }
}