如何用更好的抽象来避免类型化
How to avoid typeid with better abstraction?
我在代码中使用typeid,但在我看来,如果我避免typeid,代码可以更干净。
如果我们想存储类的类型,为什么首先要选择面向对象的语言呢?
但是我一次又一次地看到这种模式,我不知道如何避免它。
所以我在想,如果这段代码可以写得更干净,更好的抽象?
代码如下:
class A {
public:
string type;
};
template <typename T>
class B : public A {
public:
B() {
type = typeid(T).name();
}
};
class Registry {
private:
std::vector<A *> list;
public:
void append(A * a) {
int found = 0;
for (A * el : list) {
if (a->type == el->type) {
found = 1;
break;
}
}
if (!found)
list.push_back(a);
}
int size() {
return list.size();
}
};
int main(int argc, char **argv) {
Registry reg;
A * b_int1 = new B<int>();
A * b_int2 = new B<int>();
A * b_float = new B<float>();
reg.append(b_int1);
reg.append(b_int2);
reg.append(b_float);
cout << reg.size() << endl;
return 0;
}
输出为2。(这是预期的结果)
基本上我们不希望在一个列表中存储两个相同类型的对象
如果你不想要访客,但你想要一个快速的RTTI,我建议你看看这篇文章:http://www.stroustrup.com/fast_dynamic_casting.pdf
思路是:
- 每个类被分配一个不同的素数为它自己的类型(例如,
A::my_type = 2
;B::my_type = 3
) - 然后每个类被额外分配其类型和基类值的乘积,如果有的话(例如,
A::can_cast = A::my_type
;B::can_cast = B::my_type * A::can_cast;
)
这优雅地解决了is_same_dynamic()
、is_base_dynamic()
的问题:前者变成了==
,后者变成了%
。
要检查对象是否属于从给定类派生的类,可以使用dynamic_cast<T*>
并将结果与nullptr
进行比较。不幸的是,考虑到我们需要对未知类型检查这一事实,我们被迫为A
类的每个后代实现一次这样的比较方法,但这可以使用#define
来简化。
总结起来,我可能会这样写:
#define TYPE_COMPARISON
virtual bool compare(A* rhs)
{
return dynamic_cast<decltype(this)>(rhs) != nullptr;
}
class A {
public:
TYPE_COMPARISON
};
template <typename T>
class B : public A {
public:
TYPE_COMPARISON
};
class Registry {
private:
std::vector<A *> list;
public:
void append(A * a) {
int found = 0;
for (A * el : list) {
if (a->compare(el) && el->compare(a)) {
found = 1;
break;
}
}
if (!found)
list.push_back(a);
}
int size() {
return list.size();
}
};
而且,这样的方法允许您定义一个特定的后代类是否应该被视为与其父类不同。
相关文章:
- 无法创建抽象类的实例
- 如何定义一个纯抽象基类
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 用pybind11包装C++抽象类时出错
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 有没有办法按值将纯抽象类的所有子类传递给 C++ 中的函数?
- 抽象类错误,请参阅声明" "是抽象的
- 将自定义函数传递到基抽象类中以延迟执行
- 命名参数习惯用法和(抽象)基类
- 打印抽象对象 c++
- 如何在从抽象基派生的类中实现相同的方法?
- 将包含抽象类和普通类C++包导出到 Python
- C++:处理抽象类中的错误时出现问题
- C ++如何在原始抽象类中创建一个函数,该函数接受派生类的输入
- C++抽象的字节序是中立的吗?
- 在 C++ 中使用另一个头文件中的抽象类
- ATL::CComContainedObject<contained>: C2259 无法实例化抽象类
- C++:从抽象类重写纯虚拟运算符重载
- 让编译器告诉什么确切的纯虚拟方法使结构抽象?
- 如何用更好的抽象来避免类型化