Virtual destructor for polymorphic classes, const correctness, removed virtual method call in constructor

This commit is contained in:
Klaus Basan
2013-03-24 17:15:08 +01:00
parent 3b99954bdc
commit b3439ea3e4
18 changed files with 320 additions and 183 deletions

View File

@@ -5,8 +5,8 @@ namespace BlackMisc {
/**
* Constructor by integer
*/
CPhysicalQuantity::CPhysicalQuantity(qint32 baseValue, const CMeasurementUnit &unit, const CMeasurementUnit &siConversionUnit) :
_unit(unit), _conversionSiUnit(siConversionUnit)
CPhysicalQuantity::CPhysicalQuantity(qint32 baseValue, const CMeasurementUnit &unit, const CMeasurementUnit &siConversionUnit, const CPhysicalQuantityUnitConverter unitConverter) :
_pUnit(unit), _pConversionSiUnit(siConversionUnit), _unitConverter(unitConverter)
{
this->setUnitValue(baseValue);
}
@@ -14,8 +14,8 @@ CPhysicalQuantity::CPhysicalQuantity(qint32 baseValue, const CMeasurementUnit &u
/**
* Constructor by double
*/
CPhysicalQuantity::CPhysicalQuantity(double baseValue, const CMeasurementUnit &unit, const CMeasurementUnit &siConversionUnit) :
_unit(unit), _conversionSiUnit(siConversionUnit)
CPhysicalQuantity::CPhysicalQuantity(double baseValue, const CMeasurementUnit &unit, const CMeasurementUnit &siConversionUnit, const CPhysicalQuantityUnitConverter unitConverter) :
_pUnit(unit), _pConversionSiUnit(siConversionUnit),_unitConverter(unitConverter)
{
this->setUnitValue(baseValue);
}
@@ -25,7 +25,15 @@ CPhysicalQuantity::CPhysicalQuantity(double baseValue, const CMeasurementUnit &u
*/
CPhysicalQuantity::CPhysicalQuantity(const CPhysicalQuantity &otherQuantity) :
_unitValueD(otherQuantity._unitValueD), _unitValueI(otherQuantity._unitValueI), _convertedSiUnitValueD(otherQuantity._convertedSiUnitValueD),
_isIntegerBaseValue(otherQuantity._isIntegerBaseValue), _unit(otherQuantity._unit), _conversionSiUnit(otherQuantity._conversionSiUnit)
_isIntegerBaseValue(otherQuantity._isIntegerBaseValue), _pUnit(otherQuantity._pUnit), _pConversionSiUnit(otherQuantity._pConversionSiUnit), _unitConverter(otherQuantity._unitConverter)
{
// void
}
/*!
* Destructor
*/
CPhysicalQuantity::~CPhysicalQuantity()
{
// void
}
@@ -56,24 +64,24 @@ CLogMessage operator <<(CLogMessage d, const CPhysicalQuantity &quantity)
bool CPhysicalQuantity::operator ==(const CPhysicalQuantity &otherQuantity) const
{
if(this == &otherQuantity) return true;
if(this->_unit.getType()!= otherQuantity._unit.getType()) return false;
if(this->_pUnit.getType()!= otherQuantity._pUnit.getType()) return false;
// some special case for best quality
double diff;
const double lenient = 1.001; // even diff alread has a round issue
if (this->_unit == otherQuantity._unit) {
if (this->_pUnit == otherQuantity._pUnit) {
// same unit
if (this->_isIntegerBaseValue && otherQuantity._isIntegerBaseValue) {
// pure integer comparison, no rounding issues
return this->_unitValueI == otherQuantity._unitValueI;
} else {
diff = abs(this->_unitValueD - otherQuantity._unitValueD);
return diff <= (lenient * this->_unit.getEpsilon());
return diff <= (lenient * this->_pUnit.getEpsilon());
}
} else {
// based on SI value
diff = abs(this->_convertedSiUnitValueD - otherQuantity._convertedSiUnitValueD);
return diff <= (lenient * this->_unit.getEpsilon());
return diff <= (lenient * this->_pUnit.getEpsilon());
}
}
@@ -97,8 +105,9 @@ CPhysicalQuantity& CPhysicalQuantity::operator=(const CPhysicalQuantity &otherQu
CPhysicalQuantity::_unitValueD = otherQuantity._unitValueD;
CPhysicalQuantity::_convertedSiUnitValueD = otherQuantity._convertedSiUnitValueD;
CPhysicalQuantity::_isIntegerBaseValue = otherQuantity._isIntegerBaseValue;
CPhysicalQuantity::_unit = otherQuantity._unit;
CPhysicalQuantity::_conversionSiUnit = otherQuantity._conversionSiUnit;
CPhysicalQuantity::_pUnit = otherQuantity._pUnit;
CPhysicalQuantity::_pConversionSiUnit = otherQuantity._pConversionSiUnit;
CPhysicalQuantity::_unitConverter = otherQuantity._unitConverter;
return *this;
}
@@ -107,7 +116,7 @@ CPhysicalQuantity& CPhysicalQuantity::operator=(const CPhysicalQuantity &otherQu
*/
CPhysicalQuantity &CPhysicalQuantity::operator +=(const CPhysicalQuantity &otherQuantity)
{
if (this->_unit == otherQuantity._unit) {
if (this->_pUnit == otherQuantity._pUnit) {
// same unit
if (this->_isIntegerBaseValue && otherQuantity._isIntegerBaseValue) {
// pure integer, no rounding issues
@@ -116,7 +125,7 @@ CPhysicalQuantity &CPhysicalQuantity::operator +=(const CPhysicalQuantity &other
this->setUnitValue(otherQuantity._unitValueI + this->_unitValueI);
}
} else {
double v = otherQuantity.value(this->_unit);
double v = otherQuantity.value(this->_pUnit);
this->setUnitValue(v + this->_unitValueD);
}
return *this;
@@ -128,7 +137,7 @@ CPhysicalQuantity &CPhysicalQuantity::operator +=(const CPhysicalQuantity &other
CPhysicalQuantity &CPhysicalQuantity::operator +=(double unprefixedSiUnitValue)
{
if (!this->isUnprefixedSiUnit()) {
this->switchUnit(this->_conversionSiUnit);
this->switchUnit(this->_pConversionSiUnit);
}
this->setUnitValue(this->_unitValueD + unprefixedSiUnitValue);
return *this;
@@ -137,7 +146,7 @@ CPhysicalQuantity &CPhysicalQuantity::operator +=(double unprefixedSiUnitValue)
/**
* Plus operator
*/
const CPhysicalQuantity CPhysicalQuantity::operator +(const CPhysicalQuantity &otherQuantity) const
CPhysicalQuantity CPhysicalQuantity::operator +(const CPhysicalQuantity &otherQuantity) const
{
CPhysicalQuantity pq = (*this);
return pq+= otherQuantity;
@@ -148,7 +157,7 @@ const CPhysicalQuantity CPhysicalQuantity::operator +(const CPhysicalQuantity &o
*/
CPhysicalQuantity &CPhysicalQuantity::operator -=(const CPhysicalQuantity &otherQuantity)
{
if (this->_unit == otherQuantity._unit) {
if (this->_pUnit == otherQuantity._pUnit) {
// same unit
if (this->_isIntegerBaseValue && otherQuantity._isIntegerBaseValue) {
// pure integer, no rounding issues
@@ -157,7 +166,7 @@ CPhysicalQuantity &CPhysicalQuantity::operator -=(const CPhysicalQuantity &other
this->setUnitValue(otherQuantity._unitValueI - this->_unitValueI);
}
} else {
double v = otherQuantity.value(this->_unit);
double v = otherQuantity.value(this->_pUnit);
this->setUnitValue(v - this->_unitValueD);
}
return *this;
@@ -175,7 +184,7 @@ CPhysicalQuantity &CPhysicalQuantity::operator -=(double unprefixedSiUnitValue)
/**
* Minus operator
*/
const CPhysicalQuantity CPhysicalQuantity::operator -(const CPhysicalQuantity &otherQuantity) const
CPhysicalQuantity CPhysicalQuantity::operator -(const CPhysicalQuantity &otherQuantity) const
{
CPhysicalQuantity pq = (*this);
return pq-= otherQuantity;
@@ -193,7 +202,7 @@ CPhysicalQuantity &CPhysicalQuantity::operator *=(double multiply)
/**
* Multiply operator
*/
const CPhysicalQuantity CPhysicalQuantity::operator *(double multiply) const
CPhysicalQuantity CPhysicalQuantity::operator *(double multiply) const
{
CPhysicalQuantity pq= (*this);
return pq *= multiply;
@@ -211,7 +220,7 @@ CPhysicalQuantity &CPhysicalQuantity::operator /=(double divide)
/**
* Divide operator /=
*/
const CPhysicalQuantity CPhysicalQuantity::operator /(double divide) const
CPhysicalQuantity CPhysicalQuantity::operator /(double divide) const
{
CPhysicalQuantity pq= (*this);
return pq /= divide;
@@ -223,7 +232,7 @@ const CPhysicalQuantity CPhysicalQuantity::operator /(double divide) const
bool CPhysicalQuantity::operator <(const CPhysicalQuantity &otherQuantity) const {
if(this == &otherQuantity) return false;
double diff = this->_convertedSiUnitValueD - otherQuantity._convertedSiUnitValueD;
return (diff < 0 && abs(diff) >= this->_unit.getEpsilon());
return (diff < 0 && abs(diff) >= this->_pUnit.getEpsilon());
}
bool CPhysicalQuantity::operator >(const CPhysicalQuantity &otherQuantity) const {
@@ -246,10 +255,10 @@ bool CPhysicalQuantity::operator <=(const CPhysicalQuantity &otherQuantity) cons
*/
bool CPhysicalQuantity::switchUnit(const CMeasurementUnit &newUnit)
{
if (this->_unit == newUnit) return true;
if (this->_unit.getType() != newUnit.getType()) return false; // not possible
double cf = this->calculateValueInOtherUnit(newUnit);
this->_unit = newUnit;
if (this->_pUnit == newUnit) return true;
if (this->_pUnit.getType() != newUnit.getType()) return false; // not possible
double cf = this->_unitConverter(this, newUnit);
this->_pUnit = newUnit;
this->setUnitValue(cf);
return true;
}
@@ -280,17 +289,17 @@ void CPhysicalQuantity::setUnitValue(double baseValue)
* Set SI value
*/
void CPhysicalQuantity::setConversionSiUnitValue() {
this->_convertedSiUnitValueD = this->calculateValueInOtherUnit(this->_conversionSiUnit);
this->_convertedSiUnitValueD = this->_unitConverter(this, this->_pConversionSiUnit);
}
/**
* Standard conversion by factor, used in most cases,in some cases overridden (e.g.CTemperature)
* Standard conversion by factor, used in most cases, in some cases (e.g. CTemperature) arbitrary converter
*/
double CPhysicalQuantity::calculateValueInOtherUnit(const CMeasurementUnit &otherUnit) const {
if (this->_unit == CMeasurementUnit::None() || this->_unitValueD == 0.0) return 0.0;
if (this->_unit == otherUnit) return this->_unitValueD;
double f = this->_unit.conversionFactor(otherUnit);
return f * this->_unitValueD;
double CPhysicalQuantity::standardUnitFactorValueConverter(const CPhysicalQuantity *quantity, const CMeasurementUnit &otherUnit) {
if (quantity->_pUnit == CMeasurementUnit::None() || quantity->_unitValueD == 0.0) return 0.0;
if (quantity->_pUnit == otherUnit) return quantity->_unitValueD;
double f = quantity->_pUnit.conversionFactor(otherUnit);
return f * quantity->_unitValueD;
}
/**
@@ -298,7 +307,7 @@ double CPhysicalQuantity::calculateValueInOtherUnit(const CMeasurementUnit &othe
*/
double CPhysicalQuantity::unitValueToDoubleRounded(int digits) const
{
if (digits < 1) digits = this->_unit.getDisplayDigits();
if (digits < 1) digits = this->_pUnit.getDisplayDigits();
return CPhysicalQuantity::round(this->_unitValueD, digits);
}
@@ -317,7 +326,7 @@ QString CPhysicalQuantity::toQStringRounded(double value, int digits)
*/
QString CPhysicalQuantity::unitValueToQStringRounded(int digits) const
{
if (digits < 1) digits = this->_unit.getDisplayDigits();
if (digits < 1) digits = this->_pUnit.getDisplayDigits();
return CPhysicalQuantity::toQStringRounded(this->_unitValueD, digits);
}
@@ -326,7 +335,7 @@ QString CPhysicalQuantity::unitValueToQStringRounded(int digits) const
*/
QString CPhysicalQuantity::convertedSiValueToQStringRounded(int digits) const
{
if (digits < 1) digits = this->_conversionSiUnit.getDisplayDigits();
if (digits < 1) digits = this->_pConversionSiUnit.getDisplayDigits();
return CPhysicalQuantity::toQStringRounded(this->_convertedSiUnitValueD, digits);
}
@@ -334,16 +343,16 @@ QString CPhysicalQuantity::convertedSiValueToQStringRounded(int digits) const
* Value rounded in original unit
*/
QString CPhysicalQuantity::unitValueRoundedWithUnit(int digits) const {
if (digits < 1) digits = this->_unit.getDisplayDigits();
return this->unitValueToQStringRounded(digits).append(this->_unit.getUnitName());
if (digits < 1) digits = this->_pUnit.getDisplayDigits();
return this->unitValueToQStringRounded(digits).append(this->_pUnit.getUnitName());
}
/**
* SI base unit value with unit
*/
QString CPhysicalQuantity::convertedSiValueRoundedWithUnit(int digits) const {
if (digits < 1) digits = this->_conversionSiUnit.getDisplayDigits();
return this->convertedSiValueToQStringRounded(digits).append(this->_conversionSiUnit.getUnitName());
if (digits < 1) digits = this->_pConversionSiUnit.getDisplayDigits();
return this->convertedSiValueToQStringRounded(digits).append(this->_pConversionSiUnit.getUnitName());
}
/**
@@ -351,8 +360,8 @@ QString CPhysicalQuantity::convertedSiValueRoundedWithUnit(int digits) const {
*/
QString CPhysicalQuantity::valueRoundedWithUnit(const CMeasurementUnit &unit, int digits) const
{
if (unit == this->_unit) return this->unitValueRoundedWithUnit(digits);
if (unit == this->_conversionSiUnit) return this->convertedSiValueRoundedWithUnit(digits);
if (unit == this->_pUnit) return this->unitValueRoundedWithUnit(digits);
if (unit == this->_pConversionSiUnit) return this->convertedSiValueRoundedWithUnit(digits);
if (digits < 0) digits = unit.getDisplayDigits();
return CPhysicalQuantity::toQStringRounded(this->value(unit), digits).append(unit.getUnitName());
}
@@ -371,8 +380,8 @@ double CPhysicalQuantity::valueRounded(const CMeasurementUnit &unit, int digits)
*/
double CPhysicalQuantity::value(const CMeasurementUnit &unit) const
{
if (unit == this->_conversionSiUnit) return this->_convertedSiUnitValueD;
double v = this->calculateValueInOtherUnit(unit);
if (unit == this->_pConversionSiUnit) return this->_convertedSiUnitValueD;
double v = this->_unitConverter(this, unit);
return v;
}
@@ -381,7 +390,7 @@ double CPhysicalQuantity::value(const CMeasurementUnit &unit) const
*/
double CPhysicalQuantity::convertedSiValueToDoubleRounded(int digits) const
{
if (digits < 1) digits = this->_conversionSiUnit.getDisplayDigits();
if (digits < 1) digits = this->_pConversionSiUnit.getDisplayDigits();
return CPhysicalQuantity::round(this->_convertedSiUnitValueD, digits);
}