Объекты-функции. Предикаты

Неперегружаемые операторы

Индексирование

Преобразование

complex::operator double() const
{
return (m_re*m_re-m_im*m_im);
}
// вместо
double complex::norm() const
{
return (m_re*m_re-m_im*m_im);
}

double& matrix::operator() (int i,int j)
{
return (p[i][j]); // или p[i*size+j];
}

Операторы ввода/вывода

Перегрузку операторов ввода/вывода приходится оформлять в виде дружественных функций класса. При использовании оператора ввода или вывода слева от него должен находиться экземпляр потока и ничто иное. То есть перегруженные операторы ввода/вывода являются членами потоков, а не других классов. Вмешаться во внутреннюю реализацию потоков мы не можем. Но можно использовать функции, которые не являются членами классов, но позволяют получить доступ к их скрытым (private) членам.

friend ostream& operator<< (ostream& out, complex x);
friend istream& operator<< (istream& out, complex x);

ostream& operator<< (ostream& out, complex x)
{
return (out<<”(“<<x.m_re<<”,”<<x.m_im<<”)”);
}
istream& operator>>(istream& out, complex x)
{
return (in>>x.m_re>>x.m_im);
}

Не могут быть перегружены операторы следующие:

  1. :: (левый и правый операнд являются не значениями, а именем)
  2. . (правый операнд является именем)
  3. .* (правый операнд является именем)
  4. ?: (арифметический оператор имеет специфическую семантику)
  5. new (операнд является именем, кроме того выполняет небезопасную процедуру)
  6. delete (не используется без new, кроме того выполняет небезопасную процедуру)

С помощью механизма перегрузки можно переопределить только существующие операторы. Новые операторы определить невозможно.

Объекты, у которых перегружен оператор вызова функций operator().

В файле <functional> уже определено несколько полезных арифметических и других объектов-функций:

  • plus сложение
  • minus вычитание
  • multipies умножение
  • divides деление
  • modulus деление по модулю
  • negate отрицание

int main(int argc, char* argv[])
{
vector<int> v(10);
...
vector<int>::iterator i=v.begin();
while(i!= v.end())
{
*i = -(*i);
i++;
}

transform(v.begin(),v.end(), v.begin(), negate<int>()); // вместо 6 строк одна
}

Программисты могут определить свои объекты-функции:

template <class PAR>
class Rand: public unary_function<PAR, void>
{
public:
explicit Rand(int n) { srand (n); }
void operator() (PAR& i) { i=(PAR)rand(); }
};

int main(int argc, char* argv[])
{
vector<int> v(10);

vector<int>::iterator i=v.begin();
while(i!= v.end())
{
*i = rand();
i++;
}

for_each(v.begin(), v.end(), Rand<int>(5)); // вместо 6 строк одна
// если не считать объявления объекта-функции, которое впрочем будет многократно использоваться и окупится
}

Предикаты позволяют без изменения шаблона изменять критерии сравнения элементов контейнера и другие подобные действия. У предикатов объект-функция возвращает значение bool. В файле <functional> уже определено несколько полезных предикатов:

  • equal_to бинарный предикат равенства
  • not_equal_to бинарный предикат неравенства
  • greater бинарный предикат >
  • less бинарный предикат < (используется по умолчанию)
  • greater_equal бинарный предикат >=
  • less_equal бинарный предикат <=
  • logical_and бинарный предикат И
  • logical_or бинарный предикат ИЛИ
  • logical_not унарный предикат НЕ

int main(int argc, char* argv[])
{
vector<int> v(10);
for_each(v.begin(), v.end(), Rand<int>(5));

// sort(v.begin(), v.end());
// reverse(v.begin(), v.end());

sort(v.begin(), v.end(), greater<int>());

}

Аналогично программисты могут определить свои предикаты:

class InRange: public unary_function<int, bool>
{
int m_left, m_right;
public:
explicit InRange(int left, int right): m_left(left), m_right(right) {}
bool operator() (const int& i) { return (i>m_left && i<m_right); }
};

int main(int argc, char* argv[])
{
vector<int> v(10);
for_each(v.begin(), v.end(), Rand<int>(1000));
vector<int>::iterator i=v.begin();

cout << count_if(v.begin(), v.end(), InRange(1000,10000));
return 0;
}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: