与えられた:(コードは合理的な最小値に削減されました)
// メンバー タイプ
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
だからここに私の質問があります:
- これは、クラスのサイズを自動的に縮小するための合理的なアプローチですか?
- 2 つのプロパティからのみ継承すると、Particle のサイズは 1 になります。それを超えると、EmptyBase を追加するたびにサイズが 1 ずつ増加します。なぜですか?
- ここで役立つパターンやイディオムなどはありますか?
計画は、存在するプロパティに基づいて粒子の処理を自動化するテンプレートを作成することです。
私が取り組んでいるこのパーティクル システムは「リアルタイム」ではなく、膨大な量のパーティクルを処理すること、および C++ から各レンダリングを構成することを言及する必要があります。また、これはテンプレートを使用する最初の試みです。
編集: テンプレート アプローチを選択した理由は基本的に 2 つあります。2 つ目の理由は速度です。実行時に何も変更する必要がないので、テンプレートを使用して仮想関数や未使用のクラス メンバーなどのオーバーヘッドを削除できると考えました。
使用目的は、まったく同じタイプの無数のパーティクルを作成し、それらを処理してレンダリングし、コードを実行できる限り高速にすることです。:)
アイデアは、カスタム ファンクターをプラグインしてパーティクルを処理できる、高度に構成可能なシステムを用意することです。理想的には、パーティクルのプロパティは、実際に使用される場合にのみ有効になりますが、それが可能かどうか、またどのように可能かはわかりません。