- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
virtual QModelIndex parent(const QModelIndex &child) const = 0;
virtual QModelIndex sibling(int row, int column, const QModelIndex &idx) const;
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const = 0;
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const = 0;
virtual bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const = 0;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
virtual bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value,
int role = Qt::EditRole);
virtual QMap<int, QVariant> itemData(const QModelIndex &index) const;
virtual bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles);
virtual QStringList mimeTypes() const;
virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action,
int row, int column, const QModelIndex &parent) const;
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action,
int row, int column, const QModelIndex &parent);
ну, вы поняли. они написали тысячи говнокода и говорят, что это круто.
они написали говно-пример, и говорят, что это круто.
а вы что думаете по этому поводу?
вот именно. программисты на си любят свитчи. они сваливают все мыслимые и не мыслимые данные в один объект, а потом делвают switch_case по типу. и это функциональный подход. наследование и полиморфим в ооп были созданы имеено с целью избавиться от такого подхода. но тут я вижу "возвращение к истокам", и получается клубок какого-то неадекватного кода.
switch удобнее, когда добавляются новые методы, но не типы.
visitor удобнее, когда добавляются новые типы, но не методы.
А общего решения в крестах, походу, нет и не будет. wvxvw может злорадно смеяться.
Когда добавляются новые типы, но не методы - это типичный ООП с Triangle extends Shape.
Оба подхода решают одну и ту же задачу - добавление новых "виртуальных" методов к фиксированной иерархии/набору типов. При увеличении числа типов оба подхода ведут к страданиям.
У визитора visit(Base&), у switch - default.
Зато в switch управление у тебя - прерываешь обход дерева когда захочешь. А визитор - реинкарнация сраных коллбеков.
Визитор нинужен.
1) позволяет делать дефалтное поведение для необработанного типа
2) может требовать всех поддержать новый тип (тупо не скомпилится)
3) кастов там нет, но безопастность тут не главное
2) Не всегда плюс, да и несколько противоречит пункту 1, не так ли?
Алсо, в случае енумов компилятор тоже эмитит ворнинги для неразобранных кейсов без дефолта.
3) Да, в свитче нужны касты. С другой стороны, не требуется наследование и виртуальные методы и питушня с свойным диспатчингом. Олсо, ациклический визитор в стиле александреску всё же требует дайнэмик каст.
последние-то без кастов не разрулить
зубов бояться - в рот не давать, возразит публика, и будет по-своему права
Ты так говоришь, как-будто в визиторе-по-типам нет кастов... Они там всяко есть, просто инкапсулированы.
Мне в принципе нравится гошный подход
https://golang.org/doc/effective_go.html#type_switch
Хотел как-то визитор в Go написать, но потом одумался и осознал.
Если его юзать как typeswitch для полиморфного контейнера - будут. Или я сегодня туплю?
не путай с boost::any
А в более обобщенных случаях реализация модельки не напрягает, ибо один раз.
Со стороны похоже на жабу, кругом унылое ооп и сырые указатели, но хотя бы не требует долбанутого препроцессора как qt.