int main() {
    using duck_ptr = std::unique_ptr<Duck>;

    std::vector<duck_ptr> ducks;
    ducks.push_back(std::make_unique<MallardDuck>());
    ducks.push_back(std::make_unique<RedheadDuck>());
    ducks.push_back(std::make_unique<RubberDuck>());
    ducks.push_back(std::make_unique<DecoyDuck>());

    for(auto& ptr : ducks) {
        ptr->display();
        ptr->swim();
        ptr->performQuack();
        ptr->performFly();
        std::cout << '\n';
    }

    ModelDuck model;
    model.display();
    std::cout << "first try to fly\n";
    model.performFly();
    std::cout << "second <better> try\n";
    model.setFlyBehavior(FlyRocketPowered{});
    model.performFly();

    return 0;
}
// duck simulation!
int main() {
    // auto_ptr is deprecated!
    typedef std::auto_ptr<Duck> duck_ptr;

    duck_ptr ducks[] = {
        duck_ptr(new MallardDuck),
        duck_ptr(new RedheadDuck),
        duck_ptr(new RubberDuck),
        duck_ptr(new DecoyDuck)
    };

    const size_t LENGTH = sizeof(ducks) / sizeof(duck_ptr);

    for(size_t i = 0; i < LENGTH; ++i) {
        ducks[i]->display();
        ducks[i]->swim();
        ducks[i]->performQuack();
        ducks[i]->performFly();
        std::cout << '\n';
    }

    ModelDuck model;
    model.display();
    std::cout << "first try to fly\n";
    model.performFly();
    std::cout << "second <better> try\n";
    FlyWithRocketFactory flyWithRocketFactory;
    model.setFlyBehavior(flyWithRocketFactory);
    model.performFly();

    return 0;
}