Читаем Thinking In C++. Volume 2: Practical Programming полностью

In the previous example of for_each( ), the return value of the algorithm was ignored. This return value is the function that is passed in to for_each( ). If the function is just a pointer to a function, the return value is not very useful, but if it is a function object, that function object may have internal member data that it uses to accumulate information about all the objects that it sees during for_each( ).

For example, consider a simple model of inventory. Each Inventory object has the type of product it represents (here, single characters will be used for product names), the quantity of that product, and the price of each item:.

//: C06:Inventory.h

#ifndef INVENTORY_H

#define INVENTORY_H

#include

#include

#include

#ifndef _MSC_VER

// Microsoft namespace work-around

using std::rand;

using std::srand;

using std::time;

#endif

class Inventory {

  char item;

  int quantity;

  int value;

public:

  Inventory(char it, int quant, int val)

    : item(it), quantity(quant), value(val) {}

  // Synthesized operator= & copy-constructor OK

  char getItem() const { return item; }

  int getQuantity() const { return quantity; }

  void setQuantity(int q) { quantity = q; }

  int getValue() const { return value; }

  void setValue(int val) { value = val; }

  friend std::ostream& operator<<(

    std::ostream& os, const Inventory& inv) {

    return os << inv.item << ": "

      << "quantity " << inv.quantity

      << ", value " << inv.value;

  }

};

// A generator:

struct InvenGen {

  InvenGen() { srand(time(0)); }

  Inventory operator()() {

    static char c = 'a';

    int q = rand() % 100;

    int v = rand() % 500;

    return Inventory(c++, q, v);

  }

};

#endif // INVENTORY_H ///:~

Member functions get the item name and get and set quantity and value. An operator<< prints the Inventory object to an ostream. A generator creates objects that have sequentially labeled items and random quantities and values.

To find out the total number of items and total value, you can create a function object to use with for_each( ) that has data members to hold the totals:.

//: C06:CalcInventory.cpp

// More use of for_each()

#include "Inventory.h"

#include "PrintSequence.h"

#include

#include

using namespace std;

// To calculate inventory totals:

class InvAccum {

  int quantity;

  int value;

public:

  InvAccum() : quantity(0), value(0) {}

  void operator()(const Inventory& inv) {

    quantity += inv.getQuantity();

    value += inv.getQuantity() * inv.getValue();

  }

  friend ostream&

  operator<<(ostream& os, const InvAccum& ia) {

    return os << "total quantity: "

      << ia.quantity

      << ", total value: " << ia.value;

  }

};

int main() {

  vector vi;

  generate_n(back_inserter(vi), 15, InvenGen());

  print(vi.begin(), vi.end(), "vi");

  InvAccum ia = for_each(vi.begin(),vi.end(),

    InvAccum());

  cout << ia << endl;

} ///:~

InvAccum’s operator( ) takes a single argument, as required by for_each( ). As for_each( ) moves through its range, it takes each object in that range and passes it to InvAccum::operator( ), which performs calculations and saves the result. At the end of this process, for_each( ) returns the InvAccum object that you can then examine; in this case, it is simply printed.

You can do most things to the Inventory objects using for_each( ). For example, for_each( ) can handily increase all the prices by 10%. But you’ll notice that the Inventory objects have no way to change the item value. The programmers who designed Inventory thought this was a good idea. After all, why would you want to change the name of an item? But marketing has decided that they want a "new, improved" look by changing all the item names to uppercase; they’ve done studies and determined that the new names will boost sales (well, marketing has to have something to do …). So for_each( ) will not work here, but transform( ) will:

//: C06:TransformNames.cpp

// More use of transform()

#include

#include

#include

#include "Inventory.h"

#include "PrintSequence.h"

using namespace std;

struct NewImproved {

  Inventory operator()(const Inventory& inv) {

    return Inventory(toupper(inv.getItem()),

      inv.getQuantity(), inv.getValue());

  }

};

int main() {

  vector vi;

  generate_n(back_inserter(vi), 15, InvenGen());

  print(vi.begin(), vi.end(), "vi");

  transform(vi.begin(), vi.end(), vi.begin(),

    NewImproved());

  print(vi.begin(), vi.end(), "vi");

} ///:~

Notice that the resulting range is the same as the input range; that is, the transformation is performed in place.

Now suppose that the sales department needs to generate special price lists with different discounts for each item. The original list must stay the same, and any number of special lists need to be generated. Sales will give you a separate list of discounts for each new list. To solve this problem, we can use the second version of transform( ):

//: C06:SpecialList.cpp

// Using the second version of transform()

#include

#include

#include

#include

#include "Inventory.h"

#include "PrintSequence.h"

using namespace std;

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных