无论如何从静态基类方法中获取类型?例如
{{1}}
由于C ++缺少静态变量重载,我很难找到一种方法来确定跨类的类类型,而不是在每个子类中都有一个特殊的虚函数,我试图避免由于它的数量。 / p>
答案 0 :(得分:2)
创建一个将成为模板的课程
它的子类。将子类型作为模板参数传递
有了这个,基类就会知道孩子。 T
将是子类型。
代码:
#include <iostream>
using namespace std;
template<typename T> class thebase
{
static T instance;
public:
static T& getInstance() { return instance; }
};
template <typename T> T thebase<T>::instance;
class sub1 : public thebase<sub1> {
public: void tell() { std::cout << "hello1: " << this << std::endl; }
};
class sub2 : public thebase<sub2> {
public: void tell() { std::cout << "hello2: " << this << std::endl; }
};
int main() {
sub1& ref1 = sub1::getInstance();
sub1& ref2 = sub1::getInstance();
std::cout << ((&ref1) == (&ref2)) << std::endl;
sub1::getInstance().tell();
sub2::getInstance().tell();
sub1::getInstance().tell();
sub2::getInstance().tell();
return 0;
}
输出:
1
hello1: 0x55874bff1193
hello2: 0x55874bff1192
hello1: 0x55874bff1193
hello2: 0x55874bff1192
这种代码模式有时称为CRTP
答案 1 :(得分:2)
归结为有一个经理类可以跟踪各种类及其状态的一个实例。你可以使用这个单例&#34;实例&#34;这些子类,但我希望能够说MySubClass :: instance(),然后让它从管理器中获取正确的实例,而不必在每个子类中编写它。
您可以使用CRTP ("Curiously recurring template pattern")实现托管类,以便基类知道派生类类型,然后可以将该信息委托给管理器类。
尝试这样的事情:
#include <map>
#include <typeinfo>
#include <typeindex>
class Base {
public:
virtual ~Base() {}
};
class Manager
{
private:
static std::map<std::type_index, Base*> m_instances;
public:
template<typename T>
static void addInstance(Base *inst) {
if (!m_instances.insert(std::make_pair(std::type_index(typeid(T)), inst)).second)
throw ...; // only 1 instance allowed at a time!
}
template<typename T>
static void removeInstance() {
auto iter = m_instances.find(std::type_index(typeid(T)));
if (iter != m_instances.end())
m_instances.erase(iter);
}
template<typename T>
static T* getInstance() {
auto iter = m_instances.find(std::type_index(typeid(T)));
if (iter != m_instances.end())
return static_cast<T*>(iter->second);
return nullptr;
}
};
std::map<std::type_index, Base*> Manager::m_instances;
template<class Derived>
class A : public Base
{
public:
A() {
Manager::addInstance<Derived>(this);
}
~A() {
Manager::removeInstance<Derived>();
}
static Derived* getInstance() {
return Manager::getInstance<Derived>();
}
};
class B : public A<B>
{
...
};
class C : public A<C>
{
...
};
B b_inst;
C c_inst;
...
B *pB = B::getInstance();
if (pB) ...
C *pC = C::getInstance();
if (pC) ...
答案 2 :(得分:1)
根据你自己答案中自己的代码示例,这是最终的结果:
# include <iostream>
# include <typeinfo>
template <class T>
class A
{
public:
static const std::type_info& getClassType()
{
return typeid(T);
}
};
class B : public A<B>
{ /* ... */ };
class C : public A<C>
{ /* ... */};
class D : public A<D>
{ /* ... */};
int main()
{
B b; C c; D d;
auto& b_type = b.getClassType();
auto& c_type = c.getClassType();
auto& d_type = d.getClassType();
std::cout << b_type.name() << std::endl;
std::cout << c_type.name() << std::endl;
std::cout << d_type.name() << std::endl;
}
输出: 1B 1C 1D
答案 3 :(得分:0)
上面提到过CRTP或“奇怪的重复模板模式”。使用这个,我还没有测试过,但似乎我可以写:
template <class T>
class A
{
static std::type_info getClassType
{
return typeid(T);
}
};
class B : public A<B>
{
};
B instance;
auto my_type = instance::getClassType()