Главная->Інформатика та програмування->Содержание->Преобразования объектов в основне типы и наоборот

ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 8) онлайн

Преобразования объектов в основне типы и наоборот

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

В нашем следующем примере показано, как происходит преобразование ос- новного типа в тип, определенный пользователем. В этом примере в качестве определенного пользователем типа мы будем использовать класс Distance из предыдущих примеров, а в качестве основного типа — тип float, который мы использовали для переменной, содержащей метры.

В примере показаны оба варианта преобразования: из Distance в float и из float в Distance. Листинг программы ENGLCONV:

// englconv.cpp

// перевод длины из класса Distance в метры и обратно

#include <iostream>

using namespace std;

///////////////////////////////////////////////////////////

class Distance          // класс английских мер длины

{

  private:

    const float MTF;    // коэффициент перевода метров в футы

    int feet;

    float inches;

  public:

    // конструктор без параметров

    Distance ( ) : feet ( 0 ), inches ( 0.0 ), MTF ( 3.280833F )

      { }

    // конструктор с одним параметром,

    // переводящий метры в футы и дюймы

    Distance ( float meters ) : MTF ( 3.280833F )

      {

        float fltfeet = MTF * meters;     // переводим в футы

        feet = int ( fltfeet );           // берем число полных футов

        inches = 12 * ( fltfeet – feet ); // остаток — это дюймы

      }

    // конструктор с двумя параметрами

    Distance ( int ft, float in ) : feet ( ft ), inches ( in ), MTF ( 3.280833F )

      { }

    // получение информации от пользователя

    void getdist ( )

      {

        cout << "\nВведите футы: "; cin >> feet;

        cout << "Введите дюймы: ";  cin >> inches;

      }

    // показ информации

    void showdist ( ) const

      { cout << feet << "\'-" << inches << '\"'; }

    // оператор перевода для получения метров из футов

    operator float ( ) const

      {

 

float fracfeet = inches / 12;           // переводим дюймы в футы

        fracfeet += static_cast<float>( feet ); // добавляем целые футы

        return fracfeet / MTF;                  // переводим в метры

      }

};

///////////////////////////////////////////////////////////

int main ( )

{

  float mtrs;

  Distance dist1 = 2.35F; // используется конструктор, переводящий метры в футы и дюймы

 

  cout << "\ndist1 = "; dist1.showdist ( );

 

  mtrs = static_cast<float>( dist1 ); // используем оператор перевода в метры

 

  cout << "\ndist1 = " << mtrs << " meters\n";

 

  Distance dist2 ( 5, 10.25 ); // используем конструктор с двумя параметрами

 

  mtrs = dist2; // неявно используем перевод типа

  cout << "\ndist2 = " << mtrs << " meters\n";

 

  // dist2 = mtrs; // а вот это ошибка – так делать нельзя

  return 0;

}

 

В функции main() сначала происходит преобразование фиксированной вели- чины типа float — 2.35, представляющей собой метры, — в футы и дюймы с ис- пользованием конструктора с одним аргументом:

Distance dist1 = 2.35F;

Затем мы преобразовываем тип Distance во float в строке

mtrs = static_cast<float>( dist2 ); и

mtrs = dist2;

Результат работы программы:

dist1 = 7"-8.51949"- это то же. что и 2.35 метра dist1 = 2.35 meters- это то же, что и 7'-5.51949" dist2 = 1.78435 meters- это то же. что и 5'-10.25"

Мы увидели, как в функции main() выполняется преобразование типов с ис- пользованием простого выражения присваивания. Теперь рассмотрим процесс изнутри, в функциях класса Distance. Преобразование определенного пользова- телем типа в основной требует другого подхода, нежели преобразование основ- ного типа в определенный пользователем. Мы рассмотрим, как оба типа преоб- разований выполняются в программе ENGLCONV.

От основного к определенному пользователем

Для перехода от основного типа — в нашем случае float — к определенному поль- зователем типу, такому, как Distance, мы используем конструктор с одним аргу-

ментом. Его иногда называют конструктором преобразования. Вот как этот кон- структор выглядит в программе ENGLCONV:

Distance ( float meters ) {

float fltfeet = MTF * meters; feet = int ( fltfeet ); inches = 12 * ( fltfeet - feet );

}

Этот конструктор вызывается, когда создается объект класса Distance с од- ним аргументом. Конструктор предполагает, что аргумент представляет собой метры. Он преобразовывает аргумент в футы и дюймы и присваивает получен- ное значение объекту. Таким образом, преобразование от метров к переменной типа Distance выполняется вместе с созданием объекта в строке

Distance dist1 = 2.35;

От определенного пользователем к основному

А как же насчет преобразования от определенного пользователем типа к основ- ному? Здесь вся хитрость в том, чтобы создать что-то, называемое операцией преобразования. Вот как мы делаем это в программе ENGLCONV:

operator float ( ) {

float fracfeet = inches / 12; fracfeet += float ( feet ); return fracfeet / MTF;

}

Эта операция принимает значение объекта класса Distance, преобразовывает его в значение типа float, представляющее собой метры, и возвращает это значение. Операция может быть вызвана явно

mtrs = static_cast<float>( dist1 );

или с помощью простого присваивания

mtrs = dist2;

В обоих случаях происходит преобразование объекта типа Distance в его эк- вивалентное значение типа float, представляющее собой метры.

 

18