使用基类指针查找派生类对象的大小

blu*_*kin 19 c++ inheritance

当您不知道派生类型时,是否可以使用基类指针查找派生类对象的大小.

谢谢.

Den*_*ose 27

没有直接的方法,但你可以编写一个size()子类可以实现的虚方法.中间模板类可以自动化腿部工作.

struct base {
  virtual size_t size() const =0;
  virtual ~base() { }
};

template<typename T> 
struct intermediate : base {
  virtual size_t size() const { return sizeof(T); }
};

struct derived : intermediate<derived> 
{ };
Run Code Online (Sandbox Code Playgroud)

这确实要求您的层次结构是多态的...但是,基于对象的动态类型而不是其静态类型请求行为是多态行为定义的一部分.所以这不会在普通用例中添加v表,因为至少你可能已经有了一个虚拟析构函数.

此特定实现确实将继承树限制为单个级别,而不会进入多重继承[即,派生的类型derived将不会获得自己的覆盖size].有一个稍微复杂的变体可以解决这个问题.

struct base { /*as before */ };

template<typename Derived, typename Base>
struct intermediate : Base {
  virtual size_t size() const { return sizeof(Derived); }
};

struct derived : intermediate<derived, base>
{ };

struct further_derived : intermediate<further_derived, derived>
{ };
Run Code Online (Sandbox Code Playgroud)

基本上,这会intermediate在层次结构的每个实际层之间插入一个,每个层都覆盖size适当的行为,并从实际的基本类型派生.重复广告恶心.

//what you want
base >> derived 
     >> more_deriveder
     >> most_derivedest

//what you get
base >> intermediate<derived, base> 
     >> derived >> intermediate<more_deriveder, derived> 
     >> more_deriveder >> intermediate<most_derivedest, more_deriveder> 
     >> most_derivedest
Run Code Online (Sandbox Code Playgroud)

一些mixin类型库使用这样的方案,使得mixin可以添加到现有层次结构而不引入多重继承.就个人而言,我很少使用超过一个级别的继承,所以我不会为增加的复杂性而烦恼,但你的里程可能会有所不同.