如何覆盖父类静态变量。
所以我有父类
class DatabaseItem
{
static int instanceCount;
DatabaseItem()
{
instanceCount++;
}
};
如果我有两个继承自DatabaseItem的类,我希望每个类都记录只存在多少个类的实例。我该怎么做?
所以:
class Person : public DatabaseItem
{
// how do I make sure when I make the call int numOfpeople = Person::instanceCount;
// that I only get the number of people objects that exist & not all the DatabaseItem
// objects that exist?
};
class FoodItem : public DatabaseItem
{
// how do I make sure when I make the call int numOffoodItems = FoodItem::instanceCount;
// that I only get the number of FoodItem objects that exist & not all the DatabaseItem
// objects that exist?
};
编辑回复评论
是的但是,上面只是一个例子,如果我这样做,那么我有很多重复的代码......
所以:
class DatabaseItem
{
public:
static unsigned int instanceCount;
static Vector <unsigned int> usedIDs;
unsigned int ID;
DatabaseItem()
{
ID = nextAvailableID();
usedIDs.add( ID );
DatabaseItem::instanceCount++;
}
DatabaseItem( unsigned int nID )
{
if ( isIDFree( nID ) )
{
ID = nID;
}
else ID = nextAvailableID();
usedIDs.add( ID );
DatabaseItem::instanceCount++;
}
bool isIDFree( unsigned int nID )
{
// This is pretty slow to check EVERY element
for (int i=0; i<usedIDs.size(); i++)
{
if (usedIDs[i] == nID)
{
return false;
}
}
return true;
}
unsigned int nextAvailableID()
{
unsigned int nID = 0;
while ( true )
{
if ( isIDFree( ID ) )
{
return nID;
}
else nID++;
}
}
};
class Person {
public:
static unsigned int instanceCount;
static Vector <unsigned int> usedIDs;
unsigned int ID;
Person()
{
ID = nextAvailableID();
usedIDs.add( ID );
Person::instanceCount++;
}
Person( unsigned int nID )
{
if ( isIDFree( nID ) )
{
ID = nID;
}
else ID = nextAvailableID();
usedIDs.add( ID );
Person::instanceCount++;
}
bool isIDFree( unsigned int nID )
{
// This is pretty slow to check EVERY element
for (int i=0; i<usedIDs.size(); i++)
{
if (usedIDs[i] == nID)
{
return false;
}
}
return true;
}
unsigned int nextAvailableID()
{
unsigned int nID = 0;
while ( true )
{
if ( isIDFree( ID ) )
{
return nID;
}
else nID++;
}
}
};
..然后我必须为FoodItem,coffeeRun ....重写相同的代码。
答案 0 :(得分:1)
我认为在基类中不可能有一个静态变量,并告诉它每种类型的派生类实例有多少。相反,在每个类中都有一个静态类变量,它在构造函数中递增。
class Person : public DatabaseItem
{
static int numPersonItems ;
Person()
{
++numPersonItems ;
}
};
int DatabaseItem::numPersonItems = 0 ;
numPersonItems
是Person
个实例的数量。同样可以为FoodItem
类完成。
答案 1 :(得分:1)
使用模板来解决在每个构造函数等中更新实例计数的所有问题。
template<class T>
struct Instance
{
static unsigned int count;
Instance () { count ++; }
Instance (const Instance& o) { count ++; }
};
template<class T>
unsigned int Instance<T>::count = 0;
现在,这个模板可以被任何类继承,您需要为它们的实例计算:
class DatabaseItem : public Instance<DatabaseItem> {};
class Person : public DatabaseItem, Instance<Person> {};
class FoodItem : public DatabaseItem, Instance<FoodItem> {};
就是这样!
每当声明一个类对象时,它就会完成它的工作。它可以用作以下内容:
DatabaseItem *pD = new DatabaseItem[5];
Person obj[10];
cout<<Instance<DatabaseItem>::count<<endl; // 5 + 10 = 15
cout<<Instance<Person>::count<<endl; // 10
您无需在任何地方更新计数。
答案 2 :(得分:0)
鉴于您不能依赖基类构造函数中的虚拟分派,您需要将静态信息作为参数直接提供给它,或者将派生类提供给它,以便它可以查询静态信息本身。后者如下图所示
struct Base {
//provide whatever actual interface you need your type to have here
virtual ~Base();
};
template<typename Derived>
struct Intermediate : Base {
Intermediate() {
Derived::var++; //doesn't rely on polymorphism so ok in constructor
}
};
struct Derived : Intermediate<Derived> {
static int var;
};
根据您的具体用例,我倾向于根本不这样做,并且要么基类将唯一ID分散到所有实例,而不管类型如何,或者将ID创建移动到单独的类/方法中直接,并查询它的唯一标识符:
template<typename T>
struct UniqueID {
static some64bitIntType GetID(); //possibly non-static, lots of ways to handle this
};
struct Object {
some64bitIntType ID;
Object() : ID(UniqueID<Object>::GetID()) { }
};
或者那些东西。就个人而言,我倾向于不打算重新发布ID以供重用。这是一项额外工作的很多,除非你试图将自己限制在相对较少的实例范围内,否则几乎没有实际收益。