これらのクラスは関係がないように、私は今ので、これを行う方法を参照してくださいチェックしたい魔女のタイプを明示しなければなりません。
これを実行するDRY方法は、Nikolai N Festissovが提案したものです。私はいくつかのマイナーな変更を加えて同様の例を書いていましたが、グローバルな考え方はboost :: nocopyのようなクラスを作り、子クラスを与えられたサイズにすることです。
template< typename CheckedType, size_t FixedSize >
class SizeChecked // simple, no inheritance overload
{
public:
SizeChecked()
{
// c++0x or compilers with static_assert() available
//static_assert(sizeof(CheckedType) == FixedSize, "Type size check failed!");
BOOST_STATIC_ASSERT(sizeof(CheckedType) == FixedSize);
}
};
template< typename CheckedType >
class Size512 : public SizeChecked< CheckedType, 512 > // simple, no inheritance overload
{};
////////////////////////////////////////////////////////////////////
class A : Size512<A> // automatically check
{
};
class B : Size512<B> // automatically check
{
std::array< char, 512 > m_array;
};
class C : SizeChecked< C, 1 >
{
char m_char;
};
class D : SizeChecked< D, 4 >
{
short m_k;
char m_u;
};
int wmain()
{
// need instantiation to be checked !
//A a; // will trigger the assertion at compile time
B b; // sizeof(B) == 512 : will be fine
C c; // sizeof(C) == 1 : will be fine
//D d; // will fail because sizeof(short) + sizeof(char) != 4 !
}
注意:継承が緩やかな場合でも、子クラスを明示的にチェックする必要がありますが、チェックは継承されません。
ちなみに、DRYを増やす方法は、すべての静的アサーションを1か所に入れることです。
なぜ、サイズがすべて512(または他の魔方数)になると主張する必要がありますか?なぜなら、それは自分自身を繰り返す必要があるかどうか、そしてあなたが自分自身を繰り返さないことを望むなら、そのようなテストがどこに行かなければならないかを伝えるからです。 たとえば、512がキャッシュラインのサイズである場合、A、B、Cを「キャッシュラインに正確に適合する」という概念に関連付ける必要があり、それをどこかで表現する必要があります。 – MSN
その理由は、それらのクラスのすべてが関連しているからですが、1つの共通点は、そのサイズがちょうど512バイトの長さである必要があるということです。だからなぜ違うクラス?これは、A、B、およびCが異なるタイプのメッセージを表現するためです。 – sivabudh