我需要为类 Base 的每个后代分配唯一的整数值,这些后代应该可以通过使用指向这些类或其类型名的指针来访问。
我这样实现了
class Base {
public:
int idCompType = InvalidCompType;
virtual int getCompType() = 0;
}
然后在base的每个后代我应声明idCompType(对于模板)并覆盖getCompType(用于指针):
class Real1: public Base {
public:
int idCompType = 1;
int getCompType() override { return idCompType; }
}
现在我可以从指针到基础
找到comp类型Base *comp = getComp(...);
std::cout << comp->getCompType();
或在模板中使用typename:
template <typename T>
int getType() {
return T::idCompType;
}
如果没有在每个后代类中使用双重声明idCompType和getCompType(),有没有办法让它变得更简单?在Object Pascal中,我使用虚拟静态方法实现了这一点,但在C ++中不允许使用它们。
PS:问题不在于虚拟静态方法 - 虚拟静态方法只是可能的解决方案之一,也是我用其他语言解决问题的方法。
答案 0 :(得分:1)
我的建议:
对Base
的更改:
class Base {
public:
virtual int getCompType() = 0;
protected:
static int getNextCompType()
{
static int nextType = 0;
return ++nextType;
}
};
对派生类的更改:
class Real1: public Base {
public:
static int getCompTypeImpl()
{
static int myType = Base::getNextCompType();
return myType;
}
int getCompType() override
{
return getCompTypeImpl();
}
};
这是一个工作计划:
#include <iostream>
class Base {
public:
virtual int getCompType() = 0;
protected:
static int getNextCompType()
{
static int nextType = 0;
return ++nextType;
}
};
class Real1: public Base {
public:
static int getCompTypeImpl()
{
static int myType = Base::getNextCompType();
return myType;
}
int getCompType() override
{
return getCompTypeImpl();
}
};
class Real2: public Base {
public:
static int getCompTypeImpl()
{
static int myType = Base::getNextCompType();
return myType;
}
int getCompType() override
{
return getCompTypeImpl();
}
};
template <typename T> int getCompType()
{
return T::getCompTypeImpl();
}
int main()
{
Real1 v1;
Real2 v2;
std::cout << v1.getCompType() << std::endl;
std::cout << v2.getCompType() << std::endl;
std::cout << getCompType<Real1>() << std::endl;
std::cout << getCompType<Real2>() << std::endl;
};
输出:
1 2 1 2
答案 1 :(得分:0)
这是@ Sahu版本的略微变体。
不是在每个派生类中实现相同的getCompTypeImpl()
,而是将其放在Base
类中。
template<typename T>
static int getCompTypeImpl()
{
return getNextCompType<T>();
}
将getNextCompType()
修改为
template<typename T>
static int getNextCompType()
{
auto iter = m_table.find(std::type_index(typeid(T)));
if (iter != m_table.end())
{
return iter->second;
}
else
{
m_table.insert(std::make_pair(std::type_index(typeid(T)), ++nextType));
return nextType;
}
}
最后介绍2个新的静态数据成员。
private:
static std::map<std::type_index, int> m_table;
static int nextType;
请查看完整代码here。
不可否认,这引入了2个新的静态成员,并且做了更多的工作 比Sahu的原始版本。但是,这消除了实施方法的负担 所有派生类。
答案 2 :(得分:0)
@R Sahu的另一个变体是消除派生类中代码重复的答案:
#include <iostream>
class Base {
public:
virtual int getCompType() const = 0;
template <typename T>
static int getCompTypeOf()
{
static int compType = getNextCompType();
return compType;
}
private:
static int getNextCompType()
{
static int nextType = 0;
return ++nextType;
}
};
template <typename Derived, typename DeriveFrom = Base>
class TypeAssigner : DeriveFrom {
public:
int getCompType() const override
{
return Base::getCompTypeOf<Derived>();
}
};
class Real1: public TypeAssigner<Real1> {};
class Real2: public TypeAssigner<Real2> {};
class Real3 : public TypeAssigner<Real3, Real2> {};
int main()
{
Real1 v1;
Real2 v2;
Real3 v3;
std::cout << v1.getCompType() << '\n';
std::cout << v2.getCompType() << '\n';
std::cout << v3.getCompType() << '\n';
std::cout << Base::getCompTypeOf<Real1>() << '\n';
std::cout << Base::getCompTypeOf<Real2>() << '\n';
std::cout << Base::getCompTypeOf<Real3>() << '\n';
};