Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Пара непонятных примеров кода 
:(
    Опции темы
wowka19
Дата 29.4.2014, 02:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



Один из Qt:
Код

class QGraphicsPathItem : public QAbstractGraphicsShapeItem
 {
  public:
   enum { Type = 2 };
     int type() const { return Type; }
   ...
 };


В чем смысл строчки "enum { Type = 2 };" ? почему бы не сразу вернуть 2? Для чего локальный, никому неизвестный (внешне), безымянный, enum, да еще из одного элемента?

Второй:
Код

if ( p && p->ok() )
{
    ...
}

Встречал подобный код не раз. Разве в императивном C++ так можно? Разве p->ok() не выполнится в любом случае, независимо от p == 0 ? ошибка же? или нет?

Это сообщение отредактировал(а) wowka19 - 29.4.2014, 02:34
PM MAIL   Вверх
BlackSpace
Дата 29.4.2014, 03:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 16.4.2014

Репутация: 1
Всего: 1



wowka19,  про enum это весело, я тоже как-то в недоумении был smile 

в Книге Лафоре Роберта Объектно-ориентированное программирование в C++ 4-е издание 2004 года я встречал пояснение про такое использование enum.
В главе 7 Массивы и строки есть раздел Массивы как члены классов. В данном разделе есть пример класса stack, где и используется в таком виде enum, после чего идет пояснение такого использования.

На самом деле таким образом внутри класса определяется просто константа, общая для всех объектов класса. Это обходной путь чтобы не использовать static const nameType nameField = value. Просто не так давно ( лет 10-15 назад, судя по году издания книги ) по утверждениям того же Лафоре Роберта, не все компиляторы поддерживали конструкцию  static const nameType nameField = value.

Приведу простой пример.

Код

#include <iostream>

using namespace std;

class A {
public:
    static const int MAX = 10;
};

class B {
public:
    enum { MAX = 20 };
};

int main() {
    cout << A::MAX << endl;
    cout << B::MAX << endl;

    return 0;
}



Ну а что касается логического оператора &&, то в следующей ситуации
выражение1 && выражение2
выражение2 вычисляется только в случае, когда выражение1 вернет истину.

Вот простой пример.
Код

#include <iostream>

using namespace std;

class p{
public:
    bool ok(){
        cout << "OK "; // должны увидеть в выводе, если вычисляется ok()
        return true;
    }
};

int main() {

    p* ptr = NULL;
    p* ptr2= new p;

    if( ptr && ptr->ok() ){
        cout << "ptr" << endl;
    }

    if( ptr2 && ptr2->ok() ){
        cout << "ptr2" << endl;
    }

    delete ptr2;

    return 0;
}

Тут OK выводится один раз, когда проверяется условие с участием ptr2.

Это сообщение отредактировал(а) BlackSpace - 29.4.2014, 04:05
PM MAIL   Вверх
wowka19
Дата 29.4.2014, 05:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



Спасибо.
Кароч странный enum - для совместимости с древними компиляторами.
А условия в if() вычисляются пока есть смысл это делать (до достижения определенности). Кстати - это стандартом определено?

Это сообщение отредактировал(а) wowka19 - 29.4.2014, 05:06
PM MAIL   Вверх
k0rvin
Дата 29.4.2014, 05:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 24.1.2010

Репутация: нет
Всего: 5



Цитата(wowka19 @  29.4.2014,  05:06 Найти цитируемый пост)
А условия в if() вычисляются пока есть смысл это делать (до достижения определенности). Кстати - это стандартом определено?

Да:
Цитата

5.14 Logical AND operator



  1. The && operator groups left-to-right. The operands are both contextually converted to type bool (Clause 4). The result is true if both operands are true and false otherwise. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.

  2. The result is a bool. If the second expression is evaluated, every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second expression.




Это сообщение отредактировал(а) k0rvin - 29.4.2014, 05:49


--------------------
“Object-oriented design is the roman numerals of computing.” — Rob Pike
All software sucks
PM MAIL   Вверх
BlackSpace
Дата 29.4.2014, 06:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 16.4.2014

Репутация: 1
Всего: 1



wowka19,  enum - ничего не странный, а обычный   smile 

Логический оператор AND работает действительно так - вычисляются выражения пока есть смысл в этом. 
Если в моем примере выражение1 вернет false, то выражение2 вычислять не имеет смысла уже.
Приведу ссылку на  Черновик стандарта C++ документ 2005 года Здесь внизу 101 страницы можно прочитать о логическом операторе AND.
Также приведу ссылку на более свежий Черновик стандарта C++, документ 2013 года.
Здесь логический оператор AND описан на страницах 121-122.
PM MAIL   Вверх
wowka19
Дата 29.4.2014, 06:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



странным я его называю, потому что он безымянный:

Код

enum /* нет имени */ { Type = 2 }


Просто как-то нелепо выглядит - создается впечатление, что конструкция enum используется не по назначению. Что мешает использовать int Type ?
PM MAIL   Вверх
BlackSpace
Дата 29.4.2014, 07:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 16.4.2014

Репутация: 1
Всего: 1



wowka19, а int Type будет общим для всех объектов класса и будет возможность обращаться к нему не создавая ни одного объекта класса?
PM MAIL   Вверх
wowka19
Дата 29.4.2014, 07:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



понятно.
тогда получается "безымянный" enum - автоматом становится типом int ?
PM MAIL   Вверх
BlackSpace
Дата 29.4.2014, 07:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 16.4.2014

Репутация: 1
Всего: 1



wowka19, в enum есть перечеслители. Им при инициализации либо значение по умолчанию определяется, либо разработчик может сам задать. 

Используемое для инициализации перечеслителя выражение должно быть константным выражением.
Константное выражение - это выражение, в результате вычисления которого компилятором во время компиляции получается значение целочисленного типа.
Значение перечислителя изменить нельзя. Как следствие, сам перечислитель является константным выражением и может применяться везде, где необходимо константное выражение.
PM MAIL   Вверх
NoviceF
Дата 29.4.2014, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 13.3.2012
Где: Ростов-на-Дону

Репутация: 2
Всего: 2



Есть нюанс, не знаю как сейчас реализовано, но в книжках начала двухтысячных упоминается (по-моему это было в "Шаблоны C++"), что только перечисления являются "истиными" константами, т.к. под
Код

 static const int MAX = 10;

компилятор может выделить место в памяти, т.к. у этой константы можно взять адрес, в то время как у
Код

 enum { Type = 2 };

взять адрес нельзя. Этот факт используется где-то в шаблонах, более точную аргументацию, к сожалению, не помню и что-то быстро она не гуглится smile

PM MAIL   Вверх
azesmcar
Дата 29.4.2014, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



wowka19, самое обыкновенное обявление константы. А enum делает ее константой времени компиляции. Можно использовать для специализаций в шаблонах.
В новом стандарте C++ добавили constexpr, но до него использовался вот такой метод.

Цитата(wowka19 @  29.4.2014,  02:32 Найти цитируемый пост)
Встречал подобный код не раз. Разве в императивном C++ так можно? Разве p->ok() не выполнится в любом случае, независимо от p == 0 ? ошибка же? или нет?

Нет. Он начнет выполняться в любом случае, если перегрузить оператор && (потому кстати это не рекомендуется), а так у него своя специфика работы.

Это сообщение отредактировал(а) azesmcar - 29.4.2014, 10:34
PM   Вверх
baldina
Дата 29.4.2014, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(wowka19 @  29.4.2014,  02:32 Найти цитируемый пост)
никому неизвестный (внешне)

ну он как-бы public, так что возможно: QGraphicsPathItem::Type

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0744 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.