2015-07-09 5 views
1

У меня есть функция в чистом виртуальном классе, который наследуется несколькими классами. Эта функция выглядит примерно так:Проверка NULL для целых чисел в qt

virtual quint32 myClass::getIntValue() = 0 

В некоторых классах, inherrit этой функции значение по умолчанию должно быть возвращено, так как они не могут реализовать эту функцию (пока). Однако любой quint32, который я выбираю, также может быть действительным возвращаемым значением. Так, например, если я выбираю значение «0» для значения по умолчанию, я могу проверить возвращаемое значение как «0» и действовать соответствующим образом (например, игнорируя это значение). Однако будут случаи, когда «0» будет действительным возвращаемым значением, которое имеет смысл.

Есть ли какой-либо путь вокруг этой проблемы?

+3

исключение. – sbabbi

+1

@sbabbi Итак, каждый вызов 'getIntValue()' должен быть завернут в блок 'try-catch'? Знаете ли вы, как дорого раскручивается стопка !? Мне нравятся исключения, но они должны использоваться в непредвиденных обстоятельствах - просто вызов метода не является одним из них. – cmannett85

+0

Если вы можете использовать 'qint32' вместо' quint32', вы можете иметь -1 в качестве недопустимого значения по умолчанию и все еще что-то вроде 2 миллиардов возможных допустимых значений. Или, если вы хотите использовать 'quint32', вы можете считать значение -1 (' 0xFFFFFFFF') значением по умолчанию. Или вам нужны все возможные «quint32» как действительные? – Miki

ответ

2

Вы можете вернуть QPair или передать логическое значение & как:

виртуальный quint32 MyClass :: GetIntValue (BOOL & действует) = 0;

или

< виртуальный QPair quint32, BOOL> MyClass :: GetIntValue() = 0;

1

Если вы можете использовать дополнительный тип, используйте его.

В противном случае, поскольку вызывающий абонент getIntValue должен все равно выполнять проверки, было бы полезно заставить его выполнить проверки. Имейте метод, который может использовать вызывающий абонент, чтобы проверить, выполнено ли getIntValue. Быстрый осмотр такого API делает очевидным, что вам нужно позвонить hasGetIntValue, прежде чем использовать его. Он сам документирует не намного хуже, чем если бы вы использовали дополнительный тип.

class MyClass { 
    ... 
    virtual quint32 getIntValue() const { Q_ASSERT(false); } // or abort() 
    virtual bool hasGetIntValue() const { return false; } 
}; 

class Class : public MyClass { 
    ... 
    quint32 getIntValue() const Q_DECL_OVERRIDE { return 42; } 
    bool hasGetIntValue() const Q_DECL_OVERRIDE { return true; } 
} 

Абонент может затем проверить и избежать вызова в целом:

if (myClassInstance.hasGetIntValue()) { 
    auto value = getIntValue(); 
    ... 
} else { 
    // can't call getIntValue(), do something else 
} 

Этот подход будет ловить абонентов, которые не делают проверку на этапе выполнения.

Обратите внимание, что геттеры обычно могут быть объявлены const, а переопределения должны быть объявлены Q_DECL_OVERRIDE, чтобы убедиться, что вы фактически реализуете существующие виртуальные методы, а не добавляете новые.

Альтернативный подход заключается в том, чтобы реализовать какой-либо легкий дополнительный класс значений, если вы не можете использовать boost::optional по любой причине.

Смежные вопросы