Форум программистов, компьютерный форум CyberForum.ru

Преобразования абстрактного типа при вычислении выражений (переопределение операций) - C++

Восстановить пароль Регистрация
 
SkyCloud
Сообщений: n/a
22.04.2012, 18:24     Преобразования абстрактного типа при вычислении выражений (переопределение операций) #1
Добрый день! В процессе изучения С++ столкнулся с нетривиальной трудностью, которую сам для себя никак не могу объяснить.

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

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class DynamicTest
{
    DATA *data;                          //указатель на данные в памяти
    unsigned int num_data;                               //количество данных в памяти
public:
    DynamicTest(unsigned int num_data = 10, float *initializer = NULL); //конструктор   
    DynamicTest(float fFloat);                   //конструктор преобразования float к DynamicTest   
    DynamicTest(DynamicTest &obj);               //конструктор копирования  
    ~DynamicTest()                               //деструктор
 
    operator float();                                       //операция преобразования к типу float
    
    DynamicTest operator+(DynamicTest &op); //операция сложения
    DynamicTest operator-(DynamicTest &op); //операция вычитания
    DynamicTest operator*(DynamicTest &op)  ;   //операция умножения
    DynamicTest operator/(DynamicTest &op); //операция деления
    DynamicTest& operator=(DynamicTest &source);//операция присваивания
    DynamicTest& operator=(float f);                //операция присваивания
    
    float get_float(unsigned int i);    
    int get_int(unsigned int i);    
 
    //дружественные функции-операции
    friend DynamicTest operator+(DynamicTest& dt_op, float f_op);
    friend DynamicTest operator+(float f_op, DynamicTest& dt_op);
    friend DynamicTest operator-(DynamicTest& dt_op, float f_op);
    friend DynamicTest operator-(float f_op, DynamicTest& dt_op);
    friend DynamicTest operator*(DynamicTest& dt_op, float f_op);
    friend DynamicTest operator*(float f_op, DynamicTest& dt_op);
    friend DynamicTest operator/(DynamicTest& dt_op, float f_op);
    friend DynamicTest operator/(float f_op, DynamicTest& dt_op);
};
 
// реализация функций-членов класса и операций:
................
 
void main(void)
{
        DynamicTest a(10, iF1), b(12, iF2), c(10, iF3), d(10, iF4), e(10, iF5);   //объекты созданного типа
        DynamicTest result;                                                           //результат
 
        result = (a + c + 3) / (d + 4.57f) + e - b + 1;                           //вычисляем выражение
 
        // вывод результата:
        ........
}
Если определена операция operator float(), то компилятор сначала вычисляет выражение (a + c) в типе DynamicTest, затем преобразовывает результат к float, складывает с 3, и т.д. В конечном итоге всё выражение при вычислении постепенно приводится к float, после чего, на последнем шаге, конвертируется обратно в DynamicTest и присваивается переменной result. Откуда такая логика работы компилятора? Более того, при даже выражения типа result = a + b, где все переменные абстрактного типа, тоже вычисляются с приведением во float, который затем приводится к абстрактному типу для result. При этом теряется почти ВСЯ информация, свойственная абстрактному типу.

Если закомментировать или удалить операцию operator float(), то всё нормально, всё выражение вычисляется в DynamicTest и ничего нигде не теряется. Зато нельзя писать выражения типа float y = b, где b - переменная абстрактного типа.

Компилятор - Microsoft Visual Studio 2010. Всю описанную логику при вычислении выражения смотрел в отладчике. Полный файл текста программы приложен.

Это не настолько принципиальный момент, конечно. Операцию преобразования типа к float всегда можно реализовать в виде функции, например, get_float, которая, по сути, то же самое и делает, и даже в расширенном виде. Но всё равно хотелось бы понять, почему компилятор всё преобразовывает к базовому типу, чтобы в дальнейшем проектировать более продуманные программы. Спасибо за внимание, жду ваших ответов!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.04.2012, 18:24     Преобразования абстрактного типа при вычислении выражений (переопределение операций)
Посмотрите здесь:

Переопределение операций - значки C++
C++ Переопределение операций
Переопределение операций C++
C++ Переопределение операций
C++ Переопределение операций со строками
Переопределение операций C++
C++ Переопределение операций
C++ Переопределение операций в одномерном массиве

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ответ Создать тему
Опции темы

Текущее время: 05:33. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru