Лекции.ИНФО


Используя следующий формат спецификации компоновки, можно задать не одну, а сразу несколько функций.



extern "язык" {

 прототипы_функций

}

Спецификации компоновки используются довольно редко, и вам, возможно, никогда не придется их применять. Основное их назначение — позволить применение в С++-программах кода, написанного сторонними организациями на языках, отличных от C++.

Операторы указания на члены ".*" и "->*"

Операторы указания на член позволяют получить доступ к члену класса через указатель на этот член.

В C++ предусмотрена возможность сгенерировать указатель специального типа, который "ссылается" не на конкретный экземпляр члена в объекте, а на член класса вообще. Указатель такого типа называется указателем на член класса (pointer-to-member). Это — не обычный С++-указатель. Этот специальный указатель обеспечивает только соответствующее смещение в объекте, которое позволяет обнаружить нужный член класса. Поскольку указатели на члены — не настоящие указатели, к ним нельзя применять операторы "." и "->". Для получения доступа к члену класса через указатель на член необходимо использовать специальные операторы ".*" и "->*".

Если идея, изложенная в предыдущем абзаце, вам показалась немного "туманной", то следующий пример поможет ее прояснить. При выполнении этой программы отображается сумма чисел от 1 до 7. Здесь доступ к членам класса myclass (функции sum_it() и переменной sum) реализуется путем использования указателей на члены.

// Пример использования указателей на члены класса.

#include <iostream>

using namespace std;

class myclass {

 public:

  int sum;

  void myclass::sum_it(int x);

};

void myclass::sum_it(int x) {

 int i;

 sum = 0;

 for(i=x; i; i--) sum += i;

}

Int main()

{

 int myclass::*dp; // указатель на int-член класса

 void (myclass::*fp)(int x); // указатель на функцию-член

 myclass с;

 dp = &myclass::sum; // получаем адрес члена данных

 fp = &myclass::sum_it; // получаем адрес функции-члена

 (c.*fp)(7); // вычисляем сумму чисел от 1 до 7

 cout << "Сумма чисел от 1 до 7 равна " << с.*dp;

 return 0;

}

Результат выполнения этой программы таков.

Сумма чисел от 1 до 7 равна 28

В функции main() создается два члена-указателя: dp (для указания на переменную sum) и fp (для указания на функцию sum_it()). Обратите внимание на синтаксис каждого объявления. Для уточнения класса используется оператор разрешения контекста (оператор разрешения области видимости). Программа также создает объект типа myclass с именем с.

Затем программа получает адреса переменной sum и функции sum_it() и присваивает их указателям dp и fp соответственно. Как упоминалось выше, эти адреса в действительности представляют собой лишь смещения в объекте типа myclass, по которым можно найти переменную sum и функцию sum_it(). Затем программа использует указатель на функцию fp, чтобы вызвать функцию sum_it() для объекта с. Наличие дополнительных круглых скобок объясняется необходимостью корректно применить оператор ".*". Наконец, программа отображает значение суммы чисел, получая доступ к переменной sum объекта с через указатель dp.

При доступе к члену объекта с помощью объекта или ссылки на него необходимо использовать оператор ".*". Но если для этого используется указатель на объект, нужно использовать оператор "->*", как показано в этой версии предыдущей программы.

#include <iostream>

using namespace std;

class myclass {

 public:

  int sum;

  void myclass::sum_it(int x);

};

void myclass::sum_it(int x) {

 int i;

 sum = 0;

 for(i=x; i; i--) sum += i;

}

Int main()

{

 int myclass::*dp; // указатель на int-член класса

 void (myclass::*fp)(int x); // указатель на функцию-член

 myclass *c, d; // член с сейчас -- указатель на объект

 с = &d; // присваиваем указателю с адрес объекта

 dp = &myclass::sum; // получаем адрес члена данных sum

 fp = &myclass::sum_it; // получаем адрес функции sum_it()

 (c->*fp) (7); // Теперь используем оператор для вызова функции sum_it().

 cout << "Сумма чисел от 1 до 7 равна " << c->*dp; // ->*

 return 0;

}

В этой версии переменная с объявляется как указатель на объект типа myclass, а для доступа к члену данных sum и функции-члену sum_it() используется оператор "->*".

Помните, что операторы указания на члены класса предназначены для специальных случаев, и их не стоит использовать для решения обычных повседневных задач программирования.


Создание функций преобразования

Функция преобразования автоматически преобразует тип класса в другой тип.

Иногда возникает необходимость в одном выражении объединить созданный программистом класс с данными других типов. Несмотря на то что перегруженные операторные функции могут обеспечить использование смешанных типов данных, в некоторых случаях все же можно обойтись простым преобразованием типов. И тогда, чтобы преобразовать класс в тип, совместимый с типом остальной части выражения, можно использовать функцию преобразования типа. Общий формат функции преобразования типа имеет следующий вид.

operator type() {return value;}

Здесь элемент type — новый тип, который является целью нашего преобразования, а элемент value— значение после преобразования. Функция преобразования должна быть членом класса, для которого она определяется.

Чтобы проиллюстрировать создание функции преобразования, воспользуемся классом three_d еще раз. Предположим, что нам нужно иметь средство преобразования объекта типа three_d в целочисленное значение, которое можно использовать в целочисленном выражении. Более того, такое преобразование должно происходить с использованием произведения значений трех координат. Для реализации этого мы будем использовать функцию преобразования, которая выглядит следующим образом,

operator int() { return х * у * z; }

Теперь рассмотрим программу, которая иллюстрирует работу функции преобразования.

#include <iostream>

using namespace std;

class three_d {

  int x, y, z; // 3-мерные координаты

 public:

  three_d(int a, int b, int с) { x = a; у = b; z = c; }

  three_d operator+(three_d op2);

  friend ostream &operator<<(ostream &stream, three_d &obj);

  operator int() {return x * у * z; }

};

/* Отображение координат X, Y, Z - функция вывода данных для класса three_d.

*/

ostream &operator<<(ostream &stream, three_d &obj)

{

 stream << obj.x << ", ";

 stream << obj.у << ", ";

 stream << obj.z << "";

 return stream;

}

three_d three_d::operator+(three_d op2)

{

 three_d temp(0, 0, 0);

 temp.x = x+op2.x;

 temp.у = y+op2.y;

 temp.z = z+op2.z;

 return temp;

}

Int main()

{

 three_d a(1, 2, 3), b(2, 3, 4);

 cout << a << b;

 cout << b+100; /* Отображает число 124, поскольку здесь выполняется преобразование объекта класса в значение типа int. */

 cout << "";

 а = а + b; // Сложение двух объектов класса three_d выполняется без преобразования типа.

 cout << а; // Отображает координаты 3, 5, 7

 return 0;

}

Эта программа генерирует такие результаты.

1, 2, 3

2, 3, 4

3, 5, 7

Как подтверждают результаты выполнения этой программы, если в таком выражении целочисленного типа, как cout<<b+100, используется объект типа three_d, к этому объекту применяется функция преобразования. В данном случае функция преобразования возвращает значение 24, которое затем участвует в операции сложения с числом 100. Но когда в преобразовании нет необходимости, как при вычислении выражения а=а+b, функция преобразования не вызывается.

Если функция преобразования создана, то она будет вызываться везде, где требуется преобразование, включая ситуации, когда объект передается функции в качестве аргумента. Например, если объект класса three_d передать стандартной функции abs(), также будет вызвана функция, выполняющая преобразование объекта типа three_d в значение типа int, поскольку функция abs() должна принимать аргумент целочисленного типа.

Узелок на память. Для различных ситуаций можно создавать различные функции преобразования. Например, можно определить функции, которые преобразуют объекты типа three_d в значения типа double или long, при этом созданные функции будут применяться автоматически. Функции преобразования позволяют интегрировать новые типы классов, создаваемые программистом, в С++-среду программирования.









Читайте также:

  1. SWOT-анализ: характеристики при оценке сильных и слабых сторон компании, ее возможностей и угроз ей
  2. V. Несколько принципиальных соображений
  3. А можно ли сказать, что Природа есть нечто определенное?
  4. А. Можно разделить и молекулу, и атом. Б. Можно разделить молекулу, невозможно разделить атом. В. Можно разделить атом, невозможно разделить молекулу. Г. Невозможно разделить ни молекулу, ни атом.
  5. А. Переносом стальных опилок. Б. Переносом магнита. В. Переносом проводника с током. Г. Вытягиванием его с помощью сильного электромагнита. Д. Магнитное поле переместить невозможно.
  6. А. Построение кривой производственных возможностей
  7. Алгоритмы записи произвольной функции, заданной в таблице в виде с помощью элементарных функций.
  8. Анатомо-морфологическая база высших психических функций.
  9. Архитектура, принцип работы и возможности 32-разрядных ARM-микроконтроллеров серии STM 32 F100 C4
  10. Б. Сдвиги кривой производственных возможностей
  11. Без Чистой воды, без Разума, без Мировоззрения, без Кооперации – дальнейшее существование Человека на Земле невозможно.
  12. Бюджет можно рассматривать в трех аспектах: 1) материальном; 2) экономическом; 3) правовом.


Последнее изменение этой страницы: 2016-03-17; Просмотров: 99;


lektsia.info 2017 год. Все права принадлежат их авторам! Главная