如果C++不是我的主要语言,我将不胜感激。
我有一个模范班,来自多个图书馆。 我试图拿出一种办法,以独一无二地向每个衍生阶级分配id。 我需要能够用静态的方法,例如,这样做。
template < class DERIVED >
class Foo
{
public:
static int s_id()
{
// return id unique for DERIVED
}
// ...
};
Thank you!
如果C++不是我的主要语言,我将不胜感激。
我有一个模范班,来自多个图书馆。 我试图拿出一种办法,以独一无二地向每个衍生阶级分配id。 我需要能够用静态的方法,例如,这样做。
template < class DERIVED >
class Foo
{
public:
static int s_id()
{
// return id unique for DERIVED
}
// ...
};
Thank you!
在此,我结束了这项工作。 如果你有任何反馈(建议、意见),请让我知道。
template < class DERIVED >
class Foo
{
public:
static const char* name(); // Derived classes will implement, simply
// returning their class name
static int s_id()
{
static const int id = Id_factory::get_instance()->get_id(name());
return id;
}
// ...
};
基本上,在进行细微比较而不是点比较之后将分配补贴。 就速度而言,这并不理想,但我只是id静的静脉,因此只能计算每个发展经济学所一次。
几乎没有任何法典:
template < class DERIVED >
class Foo
{
public:
static int s_id()
{
return reinterpret_cast<int>(&s_id);
}
};
www.un.org/Depts/DGACM/index_spanish.htm 在现代C++(03)中,假定您使用像“gcc”这样的最近汇编者,您可使用 字面。 获取至少可操作时间提供基本类型信息的类型“信息”的关键词——该词具有标准(然后是跨平台)特征
我从阴道上举出了一个例子,并增加了一个模板/历史检查,看来在固定版本中运行良好,但并不确定(即一个黑板,利用这样一种假设,即汇编者在阅读空间中将有一些名字......可能是错误的假设)。 如果你在你的案件中能够使用这种标识,那么在交叉产品识别方面,识别标识似乎要好得多。 它没有相互兼容,因为它给你的名称是标准规定的“执行”——正如评论所建议的。 完整的测试应用代码: 产量: 这至少是关于VC10Beta1和VC9的工作,应当就海湾合作委员会开展工作。 因此,为了使用打字(和有活力的播音),你必须允许在编辑上打字。 它应当违约。 在一些板块/组件(一对一些嵌入式硬件的思考)上,RTTI由于成本而没有被放弃,因此,在某些极端情况下,你不得不找到更好的解决办法。#include <iostream>
#include <typeinfo> //for typeid to work
class Person
{
public:
// ... Person members ...
virtual ~Person() {}
};
class Employee : public Person
{
// ... Employee members ...
};
template< typename DERIVED >
class Test
{
public:
static int s_id()
{
// return id unique for DERIVED
// NOT SURE IT WILL BE REALLY UNIQUE FOR EACH CLASS!!
static const int id = reinterpret_cast<int>(typeid( DERIVED ).name());
return id;
}
static const char* s_name()
{
// return id unique for DERIVED
// ALWAYS VALID BUT STRING, NOT INT - BUT VALID AND CROSS-PLATFORM/CROSS-VERSION COMPATBLE
// AS FAR AS YOU KEEP THE CLASS NAME
return typeid( DERIVED ).name();
}
};
int wmain ()
{
Person person;
Employee employee;
Person *ptr = &employee;
std::cout << typeid(person).name() << std::endl; // Person (statically known at compile-time)
std::cout << typeid(employee).name() << std::endl; // Employee (statically known at compile-time)
std::cout << typeid(ptr).name() << std::endl; // Person * (statically known at compile-time)
std::cout << typeid(*ptr).name() << std::endl; // Employee (looked up dynamically at run-time
// because it is the dereference of a pointer to a polymorphic class)
Test<int> test;
std::cout << typeid(test).name() << std::endl;
std::cout << test.s_id() << std::endl;
std::cout << test.s_id() << std::endl;
std::cout << test.s_id() << std::endl;
std::cout << test.s_name() << std::endl;
Test< Person > test_person;
std::cout << test_person.s_name() << std::endl;
std::cout << test_person.s_id() << std::endl;
Test< Employee > test_employee;
std::cout << test_employee.s_name() << std::endl;
std::cout << test_employee.s_id() << std::endl;
Test< float > test_float;
std::cout << test_float.s_name() << std::endl;
std::cout << test_float.s_id() << std::endl;
std::cin.ignore();
return 0;
}
class Person
class Employee
class Person *
class Employee
class Test<int>
3462688
3462688
3462688
int
class Person
3421584
class Employee
3462504
float
3462872
在我以前的公司中,我们之所以这样做,是因为建立了一个宏观,将阶级名称作为参数,形成一个具有独特性(基于阶级名称)的当地静态,然后在返回静态成员的基类中确立一种虚拟功能。 这样一来,你就可以从物体等级的任何一种情况获得该身份证明,类似于ava物体的“Class()”方法,尽管更是原始。
我对迄今的答复感到不快,我为我找到了一种解决办法。 想法是用“Info”来计算一个字面。 每次在装货申请时都做过,因此没有超负荷运行。 这一解决办法还将使用共享图书馆作为名称,其名称和散射线一致。
这是我使用的法典。 这对我来说是巨大的。
#include <string>
#include <typeinfo>
#include <stdint.h>
//###########################################################################
// Hash
//###########################################################################
#if __SIZEOF_POINTER__==8
inline uint64_t hash(const char *data, uint64_t len) {
uint64_t result = 14695981039346656037ul;
for (uint64_t index = 0; index < len; ++index)
{
result ^= (uint64_t)data[index];
result *= 1099511628211ul;
}
return result;
}
#else
inline uint32_t hash(const char *data, uint32_t len) {
uint32_t result = 2166136261u;
for (uint32_t index = 0; index < len; ++index)
{
result ^= (uint32_t)data[index];
result *= 16777619u;
}
return result;
}
#endif
inline size_t hash(const std::string & str) { return hash(str.c_str(), str.length()); }
//###########################################################################
// TypeId
//###########################################################################
typedef size_t TypeId;
template<typename T>
static const std::string & typeName() {
static const std::string tName( typeid(T).name() );
return tName;
}
template<typename T>
static TypeId typeId() {
static const TypeId tId = hash( typeName<T>() );
return tId;
}
#include <stdint.h>
#include <stdio.h>
#define DEFINE_CLASS(class_name)
class class_name {
public:
virtual uint32_t getID() { return hash(#class_name); }
// djb2 hashing algorithm
uint32_t hash(const char *str)
{
unsigned long hash = 5381;
int c;
while ((c = *str++))
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash;
}
DEFINE_CLASS(parentClass)
parentClass() {};
~parentClass() {};
};
DEFINE_CLASS(derivedClass : public parentClass)
derivedClass() : parentClass() {};
~derivedClass() {};
};
int main() {
parentClass parent;
derivedClass derived;
printf("parent id: %x
derived id: %x
", parent.getID(), derived.getID());
}
何种身份识别? 你们是否指望得到原子增长? 如果扼杀是罚款,那么:
static string s_id()
{
return typeid(Foo<DERIVED>).name();
}
如果它必须是隐蔽的,但并非自动增加,那么你就可以知道,对于128个轨道的星群来说,不可能发生碰撞(尽管可能比你需要多得多)。
The following snippet work in VS(2015) and Release Building:
template <typename T>
struct TypeId
{
static size_t Get()
{
return reinterpret_cast<size_t>(&sDummy);
}
private:
static char sDummy;
};
template <typename T>
char TypeId<T>::sDummy; // don t care about value
还在海合会第7.3号(Ubuntu 1604)和LFL诉10.0.0号(Mac OS High Sierra)上进行了试验和测试。
如何运作:每个瞬时使用<代码>TypeId<>模板都有其自己的独特的大陪审团,有其独特的地址。 为了诚实,我不全心全意地确定,为什么功能-统计版本在释放时没有工作——我怀疑同志同道合和优化。
阅读器的演练:至少应当获得与原始类型相同的类型识别。
没有任何标准。 此外,我没有发现这种无ool的黑板。
最好的一号是:
template < class DERIVED, int sid >
class Foo
{
public:
static int s_id()
{
return sid;
}
};
Foo<MyClass, 123456> derivedObject;
你可以做以下工作:
#include <iostream>
template <int id = 5>
class blah
{
public:
static const int cid = id;
};
int main(int argc, char *argv[])
{
std::cout << blah<>::cid << " " << blah<10>::cid << std::endl;
}
我不知道这是否是一个好主意。 The blah<>
part is a bit unuitive. 也许你会更妥善地调换手法,或者你能够打造一个基类,给它一个与你的班子相提的模板。
_LINE__
宏观s+volaful
等关键词进行工作。
最终解决办法将探讨这样的问题:
#define GET_TYPE_ID static size_t GetTypeId()
{
volatile const char* file = __FILE__;
volatile uint32_t line = __LINE__;
return (size_t)&GetTypeId;
}
class ClassA
{
public:
GET_TYPE_ID
};
class ClassB
{
public:
GET_TYPE_ID
};