获取类中静态属性的数量
Getting the number of static attributes in a class
我有一个完全由静态属性组成的类,充当一种穷人的单例。其目的是从应用程序的各个点收集统计信息。对于我们的单元测试,我创建了一个卷影副本,可用于获取生产代码中卷影副本之间的差异。
例:
struct Production {
static ComplexClass value1;
static ComplexClass value2;
};
struct ProductionShadow {
static ComplexClass::ValueType value1;
static ComplexClass::ValueType value2;
};
由于所有成员都是静态的,因此影子类不能从生产类继承,并且生产类中的属性是具有副作用的复杂对象,我只希望影子包含简单的值进行比较。
为了使影子类更容易维护,我想添加一个静态断言来检查每当有人向生产类添加属性时,影子类也会更新。
如果属性不是静态的,则可以通过执行以下操作轻松完成此操作:
enum { NumberOfProductionAttributes = sizeof(Production) / sizeof(ComplexClass),
NumberOfShadowAttributes = sizeof(ProductionShadow) / sizeof(ComplexClass::ValueType) };
STATIC_ASSERT(NumberOfProductionAttributes == NumberOfShadowAttributes);
除了使类是非静态的(我宁愿不这样做,因为我必须将生产类变成适当的单例),有什么方法可以使用当前实现完成此检查吗?
在运行时,我有一个方法可以使用生产类验证影子中的所有值。由于添加新属性时也必须更新该方法,我希望能够计算已验证的属性数量,并断言数量是否与属性总数不同。
例
bool ProductionShadow::verify() {
std::size_t numberOfVerified = 0;
#define VERIFY(x) do {
++numberOfVerified;
// Verification code goes here
} while (0)
VERIFY(value1);
VERIFY(value2);
ASSERT(numberOfVerified == NumberOfShadowAttributes);
// Return result
}
如果有我可以使用的 GCC 扩展,这可能是一个可接受的解决方案,即使我更喜欢可移植的东西。
以防万一,这是我在问题评论中建议的解决方案。这个想法是创建两个类,它们以非静态成员的形式包含有问题的数据成员:
struct ProductionStaticMembers
{
ComplexClass value1;
ComplexClass value2;
};
struct ProductionShadowStaticMembers
{
ComplexClass::ValueType value1;
ComplexClass::ValueType value2;
};
然后重新定义原始类以包含上面定义的类作为静态成员。它们将继续像以前一样运行,并且可以针对上面定义的类型执行大小检查。
struct Production {
static ProductionStaticMembers static_members;
};
struct ProductionShadow {
static ProductionShadowStaticMembers static_members;
};
诚然,这意味着访问静态成员的方式发生了变化(因为它们现在是另一个成员的成员);因此可能需要对现有代码进行许多更改。
您可以使用inheritance
和template
的混合
enum ClassType { DEFAULT, SHADOW };
template<ClassType E>
struct Production_T
{
static ComplexClass value1;
static ComplexClass value2;
};
typedef Production_T<DEFAULT> Production;
struct ProductionShadow : Production_T<SHADOW> {
// add only new 'static' members, others are copied from 'Production_T'
};
如果某个成员被添加到Production_T
,生产影子将自动更新。因此,您不必担心在ProductionShadow
中复制成员。
你可以用宏来做到这一点。 它有点丑,但可以工作:
生产DECL.H
struct PRODUCTION_TYPE
{
PRODUCTION_VAR(ComplexClass, value1);
PRODUCTION_VAR(ComplexClass, value2);
};
生产.h
#define PRODUCTION_TYPE Production
#define PRODUCTION_VAR(type,name) static type name;
#include "productiondecl.h"
#undef PRODUCTION_TYPE
#undef PRODUCTION_VAR
生产影子.h
#define PRODUCTION_TYPE ProductionShadow
#define PRODUCTION_VAR(type,name) static type::ValueType name;
#include "productiondecl.h"
#undef PRODUCTION_TYPE
#undef PRODUCTION_VAR
如果不能在每种情况下都使用 type::ValueType,请编写一个元函数来消除类型:
template <typename T>
struct ShadowType
{
// default type is type::ValueType
typedef T::ValueType type;
};
template <> ShadowType<SomeOtherType>
{
typedef SomeOtherTypeShadow type;
}
#define PRODUCTION_VAR(type, name) static ShadowType<type>::type name;
或者,您可以避免宏并使用模板策略:
struct ComplexClass {
typedef int ValueType;
};
template <typename T>
struct ShadowType
{
typedef typename T::ValueType type;
};
template <typename T>
struct ProductionType
{
typedef T type;
};
template <template <typename T> class Policy>
struct ProductionBase
{
static typename Policy<ComplexClass>::type value1;
static typename Policy<ComplexClass>::type value2;
};
struct Production : public ProductionBase<ProductionType>
{
};
struct ProductionShadow : public ProductionBase<ShadowType>
{
};
或者,一个可怕的黑客,使用宏来避免更改生产代码:
#define Production ProductionShadow
#define ComplexClass ComplexClass::ValueType
#include "production.h"
#undef Production
#undef ComplexClass
- 静态类属性,C++中的多个构造函数
- 初始化类C++私有属性(值/引用/静态)
- 子类中具有不同值的静态基类属性
- 当应用于静态方法时,为什么constexpr属性不起作用
- LNK2001带有静态属性和方法的错误(QT,C )
- 访问指针类型的静态属性
- 如何访问带有静态回调的对象属性
- 具有静态属性(服务定位器模式)的模板继承
- 作为类的静态属性的常量内存符号
- 如何获取静态常量属性的地址?
- 如果我在一个类中有一个静态属性,并创建该类的许多新实例
- 获取类中静态属性的数量
- 如何在c++中初始化静态属性
- C++字符串上的静态属性初始化错误
- 用静态数组覆盖指针属性
- 从成员类访问非静态属性
- 静态方法更改私有属性
- 在c++中使用静态属性
- 从静态方法访问对象的属性
- 如何用静态方法改变c++中对象的属性