给定:(代码减少到合理的最小值)
// 成员类型
template
<
typename SPEEDTYPE = float,
typename SIZETYPE = float,
typename ACCELERATIONTYPE = float
>
struct ParticleMemberTypes
{
typedef typename SPEEDTYPE SpeedType;
typedef typename SIZETYPE SizeType;
typedef typename ACCELERATIONTYPE AccelerationType;
};
// 特性
template <class T>
class PSpeed
{
public:
inline const typename T::SpeedType& GetSpeed() const { return v; }
inline void SetSpeed(const typename T::SpeedType& V) { v = V; }
const static bool hasSpeed = true;
private:
typename T::SpeedType v;
};
template <class T>
class PSize
{
public:
inline const typename T::SizeType& GetSize() const { return v; }
inline void SetSize(const typename T::SizeType& V) { v = V; }
const static bool hasSize = true;
private:
typename T::SizeType v;
};
template <class T>
class PAcceleration
{
public:
inline const typename T::AccelerationType& GetAcceleration() const { return v; }
inline void SetAcceleration(const typename T::AccelerationType& V) { v = V; }
const static bool hasAcceleration = true;
private:
typename T::AccelerationType v;
};
// 空基和特化
(每个 EmptyBase 必须是不同的类型,以避免多次从同一个基类继承)
template <typename P, typename T> struct EmptyBase {};
template <typename T> struct EmptyBase<PSpeed<T>, T>
{
const static bool hasSpeed = false;
};
template <typename T> struct EmptyBase<PSize<T>, T>
{
const static bool hasSize = false;
};
template <typename T> struct EmptyBase<PAcceleration<T>, T>
{
const static bool hasAcceleration = false;
};
// 基础选择模板
template <bool ENABLE, typename P, typename T> struct EnableBase;
template <typename P, typename T> struct EnableBase<true, P, T>
{
typedef P Type;
};
template <typename P, typename T> struct EnableBase<false, P, T>
{
typedef EmptyBase<P, T> Type;
};
// 粒子模板类
template
<
bool USE_SPEED = false,
bool USE_SIZE = false,
bool USE_ACCELERATION = false,
typename T = ParticleMemberTypes<>
>
struct Particle :
public EnableBase<USE_SPEED, PSpeed<T>, T>::Type,
public EnableBase<USE_SIZE, PSize<T>, T>::Type,
public EnableBase<USE_ACCELERATION, PAcceleration<T>, T>::Type
{
};
我们现在可以这样做:
using namespace std;
Particle<> p1;
Particle<true, true, true, ParticleMemberTypes<Vector3<double> > > p2;
cout << "p1: " << sizeof(p1) << endl;
cout << "p2: " << sizeof(p2) << endl;
输出:
p1: 2
p1: 32
所以这是我的问题:
- 这是自动减小类大小的合理方法吗?
- 如果我只从两个属性继承粒子的大小为 1,除此之外,每增加一个 EmptyBase,大小就会增加一,这是为什么呢?
- 是否有任何模式、习语等在这里有用?
该计划是编写模板以根据存在的属性自动处理粒子。
我可能应该提到我正在研究的这个粒子系统不是“实时的”,将处理大量粒子,并且我将从 C++ 配置每个渲染。此外,这几乎是我第一次使用模板。
编辑:我选择模板方法基本上有两个原因:一个是好奇心 - 只是为了了解模板并探索它们的使用。第二个原因是速度。鉴于我不需要在运行时更改任何内容,我想我可以使用模板来消除虚函数和未使用的类成员等的开销。
预期用途是创建大量粒子,所有类型完全相同,并以尽可能快的速度处理和渲染它们。:)
这个想法是拥有一个高度可配置的系统,我可以在其中插入自定义函子来处理粒子。理想情况下,粒子的属性只有在实际使用时才会启用,但我还没有弄清楚是否以及如何实现。