通过继承实现类似"二维"扩展的设计类
Design classes for "two-dimension"-like expansion by inheritance
我想创建两个基本类(例如figure和move),每个类都有一些孩子(figure的立方体,球体等;移动时可以移动、旋转、缩放等)。最初的数字和移动是未知的-它必须是可扩展的。每个移动应该知道如何移动每个图形,所以有N个图形和M个移动意味着它们有N*M个函数。(添加一个移动需要为每个已经存在的图形创建N个函数,添加图形需要为每个已经存在的移动创建M个函数)。
问题是如何声明这些函数?例如,我将有一个包含图形列表(又名vector)的类Set,并且我需要要求这个类通过第I次移动所有的图形。set可能有
方法set::move_all (const move& )
…接下来呢?最简单的方法是创建虚拟方法
class figure {
...
virtual void move_this (const move& )
...
}
调用虚方法move_figure
class figure_i: public figure {
...
virtual void move_this (const move& M)
{M.move_figure(*this);
}
...
}
class move {
...
template <class T> virtual void move_figure (T&) const
...
}
并对每第i次移动进行专门化
template <> void shift::move_figure <cube> (cube& C)
{
}
等等,但是虚拟模板是非法的。
你把事情弄得太复杂了。您有一个对象集合(您称之为figures
)和一个动作集合(您称之为moves
)。从面向对象的角度来看,显而易见的选择是在figures
类中使用moves
方法。
更新
根据下面的评论,您应该使用线性代数库,如boost::ublas
。还有其他一些您可能想要研究的,例如Eigen(或多或少如下所示)。
基本思想是抽象图形和移动,以概括两者,这样您就不必为每种可能的组合重写代码。因此,您将创建一个类似于
的基类:template <typename T> class figure
{
std::vector<Eigen::Vector3d<T> > point_list;
...
void applyTransform(const Eigen::Affine3d<T>& src)
{
for (auto pt=point_list.begin(); pt != point_list.end(); pt++)
(*pt) = src * (*pt);
}
}
在这种情况下,您根据要渲染的形状定义点列表。您可以调整派生类中点的含义,以定义您感兴趣的特定几何图形。Eigen::Affine3D
类用于定义您想要应用的转换。Eigen已经定义了旋转和其他仿射变换,所以你应该能够重用它们。
你也可以查看一些专门的OpenGL或DirectX几何类,它们为你做所有这些
嗯,我目前的解决方案是使用typeid/typeinfo来识别图形/移动对,并调用相应的函数(非成员),通过从map类型的全局对象中移动图形
typedef pair<string, string> fm_pair_t;
typedef figure (*fm_act_f) (const figure& F, const move& M);
map<fm_pair_r, fm_act_f> global_fm_map;
class move {
...
figure move_figure (const figure& F) const
{map<fm_pair_r, fm_act_f>::const_iterator i =
global_fm_map.find (fm_pair_t(typeid(F).name(), typeid(*this).name()));
if (i == global_fm_map.end()) return F;
return i->second (F, *this);
}
...
};
某处和
figure cube_shift (const figure& _F, const move& _M)
{const cube& F = *dynamic_cast <const cube*> (&F);
const shift& M = *dynamic_cast <const shift*> (&M);
// act here with F and M like normal instances of cube and shift!
};
当然还有
global_fm_map(typeid(cube).name(), typeid(shift).name()) = cube_shift;
所以与使用模板的情况不同,一切都是独立的,并且可以很好地扩展。
- 将二维矢量传递给类
- 将值从二维数组输出到文本文件
- 我在二维向量中是否正确分配了内存
- 带结构的二维矢量:如何存储元素
- 在二维数组中查找最小值和最大值?
- 移动二维数组中的字符
- C++ 传递二维字符数组
- 如何正确填充在堆上分配的二维数组?
- 传递二维数组时出现问题
- 具有随机数的二维数组不会更改
- 如何在C++中获取二维数组中最少的一列数?
- 如何使用用户输入变量制作二维数组?
- C++ 中的二维整数数组,每行中的元素数量不均匀
- C++ 中动态二维数组的访问冲突
- 在二维向量或数组中可以存储的最大元素数是多少?
- 如何将整数字符串转换为整数的二维向量?
- 二维矢量数据成员
- 遍历二维数组的所有子数组
- 二维数组在 c++ 11 中的扩展
- 通过继承实现类似"二维"扩展的设计类