如何避免使用更好的抽象类型?

时间:2016-06-30 13:52:18

标签: c++

我在我的代码中使用了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.(这是预期的结果)

基本上我们不想在列表中存储两个相同类型的对象。

2 个答案:

答案 0 :(得分:1)

如果你不想要访问者,但是你想要一个快速的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()问题:前者成为==,后者成为%

答案 1 :(得分:1)

要检查对象是否属于从给定类派生的类,可以使用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();
  }
};

此外,此类方法允许您定义是否应将特定后代类视为与其父级不同。