我有一个类层次结构作为这一个:
class A { } // class AA : A { } // A class AAA : AA { } // / \ class AAB : AA { } // AA AB class AB : A { } // / \ / \ class ABA : AB { } // AAA AAB ABA ABB class ABB : AB { } //
我想模仿RTTI(当然没有使用它)对于这个ierarchy,以一种方式,给定一个指针/对A的引用,我可以找到它的实际类型(类似于typeid),作为一个整数识别课程.
此外,我希望识别我的类型的整数集是连续的,从0到N-1(在我的例子中从0到6):
class A { virtual int t(){return 0;} } // class AA : A { virtual int t(){return 1;} } // A(0) class AAA : AA { virtual int t(){return 2;} } // / \ class AAB : AA { virtual int t(){return 3;} } // AA(1) AB(4) class AB : A { virtual int t(){return 4;} } // / \ / \ class ABA : AB { virtual int t(){return 5;} } // AAA(2) AAB(3) ABA(5) ABB(6) class ABB : AB { virtual int t(){return 6;} } //
(顺序并不重要:A :: t可以返回3和AAB :: t 0,例如.
是否可以让编译器将索引分配给我的类?
我认为CRTP可以帮助我就像是:
class X : A,AssignFirstAvailableIndex< X > { }
但我不够模板.我如何实现AssignFirstAvailableIndex模板类?
(当然编译器可以在编译时看到所有的类)
解决方法
有一个标准的方法来实现你所需要的.标准区域设计使用它来识别自己.考虑检查标准标题“locale”.
class Base { public: // Being constructed contains a new unique identifier class Id { // An id factory returns a sequence of nonnegative ints static int allocate() { static int total = 0; return total++; } int _local; public: Id(): _local(allocate()) {} int get() const {return _local;} }; //Child classes should make this function return an id generated by Base::Id constructed as static member. virtual int id() const = 0; }; class Child1{ public: static const Base::Id _id; virtual int id() { return _id.get(); } }; class Child2 { public: static const Base::Id _id; virtual int id() { return _id.get(); } }; class Child3 { public: static const Base::Id _id; virtual int id() { return _id.get(); } };
静态成员可能在实现文件中进行初始化,或者被模板化以允许从头部直接实例化,也可以重构以进行延迟初始化.