在这种特殊情况下如何避免代码重复
How to avoid code duplication in this particular case
我有这些通用的 class 二维几何:
template<class T> struct Point
{
T x,y;
//...Various member functions...
//T modulus() const noexcept { ... }
//T dist_from(const Point& other) const noexcept { ... }
//...
};
template<class T> class Polygon
{
public:
// ...An awful lot of member functions...
auto size() const noexcept { return vertexes.size(); }
//T area() const noexcept {...}
//T perimeter() const noexcept {...}
//T moment_of_inertia(const Point<T>&) const noexcept {...}
//void reorder_vertexes() {...}
//void transform(const Matrix& m) {...}
// ...
private:
std::vector<Point<T>> vertexes;
};
它们运行良好,我在项目的各个部分都使用了它们。现在,对于特定的应用程序,我需要 Polygon
但还需要将一些 data
关联到它的每个顶点。
由于 Polygon
顶点可以转换和重新排序,我宁愿避免维护包含额外 data
的平行 std::vector
的额外工作。
我真的很想介绍一个新的 class 像 this:
template<class T, class D> class DecoratedPolygon
{
public:
struct DecoratedPoint
{
Point<T> point;
D data;
};
// Some specialized member functions...
const D& get_vertex_decoration(const std::size_t idx) const
{
return vertexes.at(idx).data;
}
// ...Then same member functions as polygon,
// except accessing the '.point'
auto size() const noexcept { return vertexes.size(); }
//...
private:
std::vector<DecoratedPoint> vertexes;
};
我的问题是我不想重写 Polygon
的所有成员函数的一个稍微修改过的版本。
你会如何处理这个特殊案例?我想知道是否有一种零成本技术可以避免代码重复,或者我只是走错了路。
您可以尝试参数化多边形 class 以同时采用点类型:
template <class P> class Polygon {
std::vector<P> vertices
}
template <class T> class Point {
T x,y;
}
class DecoratedPoint : Point<long> {
int extraData;
}
Polygon<DecoratedPoint> newPoly;
修饰的数据最终会来自点本身,因此界面看起来会有点不同:
Polygon {
P get_point_at_idx( const std::size_t idx) {
return points.at(idx)
}
}
my_poly.get_point_at_idx(0).extraData
您需要稍微更改多边形的实现,但从长远来看可能会提供更多控制。
我有这些通用的 class 二维几何:
template<class T> struct Point
{
T x,y;
//...Various member functions...
//T modulus() const noexcept { ... }
//T dist_from(const Point& other) const noexcept { ... }
//...
};
template<class T> class Polygon
{
public:
// ...An awful lot of member functions...
auto size() const noexcept { return vertexes.size(); }
//T area() const noexcept {...}
//T perimeter() const noexcept {...}
//T moment_of_inertia(const Point<T>&) const noexcept {...}
//void reorder_vertexes() {...}
//void transform(const Matrix& m) {...}
// ...
private:
std::vector<Point<T>> vertexes;
};
它们运行良好,我在项目的各个部分都使用了它们。现在,对于特定的应用程序,我需要 Polygon
但还需要将一些 data
关联到它的每个顶点。
由于 Polygon
顶点可以转换和重新排序,我宁愿避免维护包含额外 data
的平行 std::vector
的额外工作。
我真的很想介绍一个新的 class 像 this:
template<class T, class D> class DecoratedPolygon
{
public:
struct DecoratedPoint
{
Point<T> point;
D data;
};
// Some specialized member functions...
const D& get_vertex_decoration(const std::size_t idx) const
{
return vertexes.at(idx).data;
}
// ...Then same member functions as polygon,
// except accessing the '.point'
auto size() const noexcept { return vertexes.size(); }
//...
private:
std::vector<DecoratedPoint> vertexes;
};
我的问题是我不想重写 Polygon
的所有成员函数的一个稍微修改过的版本。
你会如何处理这个特殊案例?我想知道是否有一种零成本技术可以避免代码重复,或者我只是走错了路。
您可以尝试参数化多边形 class 以同时采用点类型:
template <class P> class Polygon {
std::vector<P> vertices
}
template <class T> class Point {
T x,y;
}
class DecoratedPoint : Point<long> {
int extraData;
}
Polygon<DecoratedPoint> newPoly;
修饰的数据最终会来自点本身,因此界面看起来会有点不同:
Polygon {
P get_point_at_idx( const std::size_t idx) {
return points.at(idx)
}
}
my_poly.get_point_at_idx(0).extraData
您需要稍微更改多边形的实现,但从长远来看可能会提供更多控制。