没有RTTI和虚拟功能。
我遇到了两种不同的通用解决方案来提供对象的类型:
使用虚方法调用并在方法中保留id:
class Base {
public:
virtual ~Base();
virtual int getType() const =0;
};
class Derived : public Base {
public:
virtual int getType() const { return DerivedID; }
};
使用内联方法调用并在基类中保留id:
class Base {
int id_;
public:
virtual ~Base();
inline int getType() const { return id_; }
};
class Derived : public Base {
public:
Derived() { id_=DerivedID;}
};
一般来说什么是更好的选择,它们的利弊是什么?
答案 0 :(得分:1)
如果在每个派生类中选择带有ID的第二个选项,则在您创建的每个对象中都会有一个额外的成员。如果你使用虚函数的第一个选项,你将在vtable中有一个额外的指针,每个类只存在一次,而不是每个对象。如果该类具有多个虚函数,则第一个选项显然更好。即使不是,我认为它更符合人们的期望。
答案 1 :(得分:0)
您不需要直接基类的虚拟继承,也不需要任何基类成员变量来支持此功能
struct Interface {
virtual void foo() = 0;
virtual int bar() = 0;
};
template<class T>
class Base : public Interface {
public:
int getType() const { return getTypeId(); }
static int getTypeId() { return T::ClassId; }
};
class Derived : public Base<Derived> {
public:
static const int ClassId = DerivedID;
virtual void foo() { }
virtual int bar() { return 1; }
};
用法就像
Derived der;
Interface* iface = &der;
iface->foo();
iface->bar();
查看工作示例here。
注意:强>
您在此类系统的当前配置中使用的所有类型都需要在编译时熟知。这并不支持Plugin pattern based机制。
答案 2 :(得分:0)
好的,我会刺伤......
“他们的利弊是什么?”
您的第一个示例virtual int getType() const =0;
会产生额外的处理开销。对于CPU来说,virtual
函数调用可能更难以抢占。 This issue may be trivial
您的第二个示例inline int getType() const { return id_; }
会产生额外的运行时存储空间。并且为每个int
的每个实例存储额外的Base
。这也可能是微不足道的。
“一般来说什么是更好的选择?”
一般来说,避免过早优化。选择基类中的纯虚函数,因为它的正确性由编译器和运行时强制执行。