不,没有这样的开关。
LLVM/Clang 代码库避免了由数以万计分配的类中的虚拟表:这在封闭的层次结构中运行良好,因为单个enum可以枚举所有可能的类,然后每个类都链接到enum. 关闭显然是enum因为。
然后,在调用该方法之前,虚拟性由 a switchon theenum和适当的强制转换实现。再次关闭。switch必须针对每个新类进行修改。
第一种选择:外部 vpointer。
如果您发现自己经常支付 vpointer 税,那么大多数对象都是已知类型的。然后,您可以将其外部化。
class Interface {
public:
  virtual ~Interface() {}
  virtual Interface* clone() const = 0; // might be worth it
  virtual void updateCount(int) = 0;
protected:
  Interface(Interface const&) {}
  Interface& operator=(Interface const&) { return *this; }
};
template <typename T>
class InterfaceBridge: public Interface {
public:
  InterfaceBridge(T& t): t(t) {}
  virtual InterfaceBridge* clone() const { return new InterfaceBridge(*this); }
  virtual void updateCount(int i) { t.updateCount(i); }
private:
  T& t; // value or reference ? Choose...
};
template <typename T>
InterfaceBridge<T> interface(T& t) { return InterfaceBridge<T>(t); }
然后,想象一个简单的类:
class Counter {
public:
  int getCount() const { return c; }
  void updateCount(int i) { c = i; }
private:
  int c;
};
您可以将对象存储在数组中:
static Counter array[5];
assert(sizeof(array) == sizeof(int)*5); // no v-pointer
并且仍然将它们与多态函数一起使用:
void five(Interface& i) { i.updateCount(5); }
InterfaceBridge<Counter> ib(array[3]); // create *one* v-pointer
five(ib);
assert(array[3].getCount() == 5);
价值与参考实际上是一种设计张力。一般来说,如果您需要,clone您需要按值存储,并且在您按基类存储时需要克隆(boost::ptr_vector例如)。实际上可以同时提供两个接口(和桥接器):
Interface <--- ClonableInterface
  |                 |
InterfaceB     ClonableInterfaceB
这只是额外的打字。
另一种解决方案,涉及更多。
切换可以通过跳转表来实现。这样的表可以在运行时完美地创建,std::vector例如:
class Base {
public:
  ~Base() { VTables()[vpointer].dispose(*this); }
  void updateCount(int i) {
    VTables()[vpointer].updateCount(*this, i);
  }
protected:
  struct VTable {
    typedef void (*Dispose)(Base&);
    typedef void (*UpdateCount)(Base&, int);
    Dispose dispose;
    UpdateCount updateCount;
  };
  static void NoDispose(Base&) {}
  static unsigned RegisterTable(VTable t) {
    std::vector<VTable>& v = VTables();
    v.push_back(t);
    return v.size() - 1;
  }
  explicit Base(unsigned id): vpointer(id) {
    assert(id < VTables.size());
  }
private:
  // Implement in .cpp or pay the cost of weak symbols.
  static std::vector<VTable> VTables() { static std::vector<VTable> VT; return VT; }
  unsigned vpointer;
};
然后,一个Derived类:
class Derived: public Base {
public:
  Derived(): Base(GetID()) {}
private:
  static void UpdateCount(Base& b, int i) {
    static_cast<Derived&>(b).count = i;
  }
  static unsigned GetID() {
    static unsigned ID = RegisterTable(VTable({&NoDispose, &UpdateCount}));
    return ID;
  }
  unsigned count;
};
好吧,现在你会意识到编译器为你做这件事是多么的棒,即使是以一些开销为代价。
哦,由于对齐,一旦一个Derived类引入一个指针,就有可能在Base和下一个属性之间使用 4 个字节的填充。您可以通过仔细选择前几个属性来使用它们Derived以避免填充...