Шаг 182.
Библиотека Qt.
Реализация класса Cell. Окончание

    На этом шаге продолжим рассматривать реализацию подкласса QTableWidgetItem.

    Закрытая функция value() возвращает значение ячейки.

const QVariant Invalid;
QVariant Cell::value() const
{
    /*Если флажок cachelsDirty имеет значение true, нам необходимо
    выполнить перерасчет значения*/
    if (cacheIsDirty) {
        cacheIsDirty = false;
        QString formulaStr = formula();
        /*Если формула начинается с одиночной кавычки (например, "'12345"),
        то одиночная кавычка занимает позицию 0, а значение представляет собой
        строку в позициях с 1 до последней*/
        if (formulaStr.startsWith('\'')) {
            cachedValue = formulaStr.mid(1);
        }
        /*Если формула начинается со знака равенства ("="),
        мы выделяем строку, начиная с позиции 1, и удаляем из нее любые пробелы.
        Затем мы вызываем функцию evalExpression() для вычисления значения
        выражения. Аргумент pos передается по ссылке; он задает позицию символа,
        с которого должен начинаться синтаксический анализ выражения. После
        вызова функции evalExpression() в позиции pos нами должен быть установлен
        символ QChar::Null, если синтаксический анализ завершился успешно. Если
        синтаксический анализ не закончился успешно, мы устанавливаем cachedValue
        на значение Invalid*/
        else if (formulaStr.startsWith('=')) {
            cachedValue = Invalid;
            QString expr = formulaStr.mid(1);
            expr.replace(" ", "");
            expr.append(QChar::Null);
            int pos = 0;
            cachedValue = evalExpression(expr, pos);
            if (expr[pos] != QChar::Null)
                cachedValue = Invalid;
        }
        /*Если формула не начинается с одиночной кавычки или знака равенства,
        мы пытаемся преобразовать ее в число с плавающей точкой, используя
        функцию toDouble(). Если преобразование удается выполнить, мы
        устанавливаем cachedValue на полученное значение; в противном случае
        устанавливаем cachedValue на строку формулы. Например, формула "1.50"
        приводит к тому, что функция toDouble() устанавливает переменную ok на
        значение true и возвращает 1.5, а формула "население Земли"
        приводит к тому, что функция toDouble()устанавливает переменную ok на
        значение false и возвращает 0.0. Благодаря заданному в функции toDouble()
        указателю на булево значение мы можем отличать строку преобразования,
        представляющую числовое значение 0.0, от ошибки преобразования (в
        последнем случае также возвращается 0.0, но булева переменная
        устанавливается в значение false). Иногда нулевое значение при неудачном
        преобразовании оказывается именно тем, что нам нужно; в этом случае нет
        необходимости передавать указать на переменную типа bool. По причинам,
        связанным с производительностью и переносимостью, в Qt никогда не
        используются исключения C++ для вывода сообщений об ошибках. Это не
        значит, что вы не можете использовать их в своих Qt-программах, если ваш
        компилятор поддерживает исключения C++*/
        else {
            bool ok;
            double d = formulaStr.toDouble(&ok);
            if (ok) {
                cachedValue = d;
            } else {
                cachedValue = formulaStr;
            }
        }
    }
    return cachedValue;
}

    Функция value() объявлена с модификатором const. При объявлении переменных cachedValue и cachelsValid мы использовали ключевое слово mutable, чтобы компилятор позволял нам модифицировать эти переменные в функциях типа const. Может показаться заманчивой возможность сделать функцию value() не типа const и удалить ключевые слова mutable, но это не пропустит компилятор, поскольку мы вызываем value() из data(), функции с модификатором const.

    На следующем шаге рассмотрим синтаксический анализ формул в приложении Электронная таблица.




Предыдущий шаг Содержание Следующий шаг