Use inheritance rather than composition for QgsReferencedGeometries

See https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392
for discussion of the rationale
This commit is contained in:
Nyall Dawson 2017-08-31 13:53:00 +10:00
parent e926f345e8
commit 1194b5abea
7 changed files with 94 additions and 60 deletions

View File

@ -42,6 +42,8 @@ Construct a rectangle from a QRectF. The rectangle is normalized after construct
Copy constructor Copy constructor
%End %End
~QgsRectangle();
void set( const QgsPointXY &p1, const QgsPointXY &p2 ); void set( const QgsPointXY &p1, const QgsPointXY &p2 );
%Docstring %Docstring
Sets the rectangle from two QgsPoints. The rectangle is Sets the rectangle from two QgsPoints. The rectangle is

View File

@ -9,21 +9,17 @@
template<T> class QgsReferencedGeometryBase
class QgsReferencedGeometryPrimitive
{ {
%Docstring %Docstring
A template based class for storing geometry primitives with an associated reference system. A base class for geometry primitives which are stored with an associated reference system.
QgsReferencedGeometryPrimitive classes represent some form of geometry primitive QgsReferencedGeometryBase classes represent some form of geometry primitive
(such as rectangles) which have an optional coordinate reference system (such as rectangles) which have an optional coordinate reference system
associated with them. associated with them.
.. versionadded:: 3.0 .. versionadded:: 3.0
.. seealso:: QgsReferencedRectangle .. seealso:: QgsReferencedRectangle
.. note::
Not available in Python bindings (although SIP file is present for specific implementations).
%End %End
%TypeHeaderCode %TypeHeaderCode
@ -31,16 +27,9 @@ class QgsReferencedGeometryPrimitive
%End %End
public: public:
QgsReferencedGeometryPrimitive( T primitive, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ); QgsReferencedGeometryBase( const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() );
%Docstring %Docstring
Constructor for QgsReferencedGeometryPrimitive, for the specified ``primitive`` and ``crs``. Constructor for QgsReferencedGeometryBase, with the specified ``crs``.
%End
T &primitive();
%Docstring
Returns the geometry primitive.
:rtype: T
%End %End
QgsCoordinateReferenceSystem crs() const; QgsCoordinateReferenceSystem crs() const;
@ -60,11 +49,7 @@ class QgsReferencedGeometryPrimitive
}; };
class QgsReferencedRectangle : QgsRectangle, QgsReferencedGeometryBase
typedef QgsReferencedGeometryPrimitive<QgsRectangle> QgsReferencedGeometryPrimitiveQgsRectangleBase;
class QgsReferencedRectangle : QgsReferencedGeometryPrimitiveQgsRectangleBase
{ {
%Docstring %Docstring
A QgsRectangle with associated coordinate reference system. A QgsRectangle with associated coordinate reference system.
@ -73,20 +58,33 @@ class QgsReferencedRectangle : QgsReferencedGeometryPrimitiveQgsRectangleBase
%TypeHeaderCode %TypeHeaderCode
#include "qgsreferencedgeometry.h" #include "qgsreferencedgeometry.h"
typedef QgsReferencedGeometryPrimitive<QgsRectangle> QgsReferencedGeometryPrimitiveQgsRectangleBase;
%End %End
public: public:
QgsReferencedRectangle( const QgsRectangle &rect ); QgsReferencedRectangle( const QgsRectangle &rectangle, const QgsCoordinateReferenceSystem &crs );
%Docstring %Docstring
Construct a default optional expression. Constructor for QgsReferencedRectangle, with the specified initial ``rectangle``
It will be disabled and with an empty expression. and ``crs``.
%End %End
QgsRectangle &rect(); };
class QgsReferencedPointXY : QgsPointXY, QgsReferencedGeometryBase
{
%Docstring %Docstring
Returns the rectangles A QgsPointXY with associated coordinate reference system.
:rtype: QgsRectangle .. versionadded:: 3.0
%End
%TypeHeaderCode
#include "qgsreferencedgeometry.h"
%End
public:
QgsReferencedPointXY( const QgsPointXY &point, const QgsCoordinateReferenceSystem &crs );
%Docstring
Constructor for QgsReferencedPointXY, with the specified initial ``point``
and ``crs``.
%End %End
}; };

View File

@ -447,6 +447,7 @@ SET(QGIS_CORE_SRCS
geometry/qgspoint.cpp geometry/qgspoint.cpp
geometry/qgspolygon.cpp geometry/qgspolygon.cpp
geometry/qgsrectangle.cpp geometry/qgsrectangle.cpp
geometry/qgsreferencedgeometry.cpp
geometry/qgsregularpolygon.cpp geometry/qgsregularpolygon.cpp
geometry/qgstriangle.cpp geometry/qgstriangle.cpp
geometry/qgswkbptr.cpp geometry/qgswkbptr.cpp

View File

@ -47,6 +47,11 @@ class CORE_EXPORT QgsRectangle
//! Copy constructor //! Copy constructor
QgsRectangle( const QgsRectangle &other ); QgsRectangle( const QgsRectangle &other );
// IMPORTANT - while QgsRectangle is inherited by QgsReferencedRectangle, we do NOT want a virtual destructor here
// because this class MUST be lightweight and we don't want the cost of the vtable here.
// see https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392
~QgsRectangle() = default;
/** /**
* Sets the rectangle from two QgsPoints. The rectangle is * Sets the rectangle from two QgsPoints. The rectangle is
* normalised after construction. * normalised after construction.

View File

@ -0,0 +1,32 @@
/***************************************************************************
qgsreferencedgeometry.cpp
------------------------
begin : June 2017
copyright : (C) 2017 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsreferencedgeometry.h"
QgsReferencedGeometryBase::QgsReferencedGeometryBase( const QgsCoordinateReferenceSystem &crs )
: mCrs( crs )
{}
QgsReferencedRectangle::QgsReferencedRectangle( const QgsRectangle &rect, const QgsCoordinateReferenceSystem &crs )
: QgsRectangle( rect )
, QgsReferencedGeometryBase( crs )
{}
QgsReferencedPointXY::QgsReferencedPointXY( const QgsPointXY &point, const QgsCoordinateReferenceSystem &crs )
: QgsPointXY( point )
, QgsReferencedGeometryBase( crs )
{}

View File

@ -25,40 +25,25 @@
#include "qgsrectangle.h" #include "qgsrectangle.h"
/** /**
* \class QgsReferencedGeometryPrimitive * \class QgsReferencedGeometryBase
* \ingroup core * \ingroup core
* A template based class for storing geometry primitives with an associated reference system. * A base class for geometry primitives which are stored with an associated reference system.
* *
* QgsReferencedGeometryPrimitive classes represent some form of geometry primitive * QgsReferencedGeometryBase classes represent some form of geometry primitive
* (such as rectangles) which have an optional coordinate reference system * (such as rectangles) which have an optional coordinate reference system
* associated with them. * associated with them.
* *
* \since QGIS 3.0 * \since QGIS 3.0
* \see QgsReferencedRectangle * \see QgsReferencedRectangle
* \note Not available in Python bindings (although SIP file is present for specific implementations).
*/ */
template<typename T> class CORE_EXPORT QgsReferencedGeometryBase
class CORE_EXPORT QgsReferencedGeometryPrimitive
{ {
public: public:
/** /**
* Constructor for QgsReferencedGeometryPrimitive, for the specified \a primitive and \a crs. * Constructor for QgsReferencedGeometryBase, with the specified \a crs.
*/ */
QgsReferencedGeometryPrimitive( T primitive, const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() ) QgsReferencedGeometryBase( const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() );
: mPrimitive( primitive )
, mCrs( crs )
{}
/**
* Returns the geometry primitive.
*/
T primitive() const { return mPrimitive; } SIP_SKIP
/**
* Returns the geometry primitive.
*/
T &primitive() { return mPrimitive; }
/** /**
* Returns the associated coordinate reference system, or an invalid CRS if * Returns the associated coordinate reference system, or an invalid CRS if
@ -76,32 +61,41 @@ class CORE_EXPORT QgsReferencedGeometryPrimitive
private: private:
T mPrimitive;
QgsCoordinateReferenceSystem mCrs; QgsCoordinateReferenceSystem mCrs;
}; };
//template class QgsReferencedGeometryPrimitive< QgsRectangle > QgsReferencedRectangle;
/** /**
* \ingroup core * \ingroup core
* A QgsRectangle with associated coordinate reference system. * A QgsRectangle with associated coordinate reference system.
* \since QGIS 3.0 * \since QGIS 3.0
*/ */
class CORE_EXPORT QgsReferencedRectangle : public QgsReferencedGeometryPrimitive< QgsRectangle > class CORE_EXPORT QgsReferencedRectangle : public QgsRectangle, public QgsReferencedGeometryBase
{ {
public: public:
/** /**
* Construct a default optional expression. * Constructor for QgsReferencedRectangle, with the specified initial \a rectangle
* It will be disabled and with an empty expression. * and \a crs.
*/ */
QgsReferencedRectangle( const QgsRectangle &rect ) : QgsReferencedGeometryPrimitive( rect ) {} QgsReferencedRectangle( const QgsRectangle &rectangle, const QgsCoordinateReferenceSystem &crs );
};
/**
* \ingroup core
* A QgsPointXY with associated coordinate reference system.
* \since QGIS 3.0
*/
class CORE_EXPORT QgsReferencedPointXY : public QgsPointXY, public QgsReferencedGeometryBase
{
public:
/** /**
* Returns the rectangles * Constructor for QgsReferencedPointXY, with the specified initial \a point
* and \a crs.
*/ */
QgsRectangle &rect() { return primitive(); } QgsReferencedPointXY( const QgsPointXY &point, const QgsCoordinateReferenceSystem &crs );
}; };

View File

@ -91,8 +91,10 @@ class CORE_EXPORT QgsPointXY
*/ */
QgsPointXY( const QgsPoint &point ); QgsPointXY( const QgsPoint &point );
~QgsPointXY() // IMPORTANT - while QgsPointXY is inherited by QgsReferencedPointXY, we do NOT want a virtual destructor here
{} // because this class MUST be lightweight and we don't want the cost of the vtable here.
// see https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392
~QgsPointXY() = default;
/** Sets the x value of the point /** Sets the x value of the point
* \param x x coordinate * \param x x coordinate