【问题标题】:Using a class with a template base class as a base class argument使用具有模板基类的类作为基类参数
【发布时间】:2011-06-12 22:30:05
【问题描述】:

我在这里遗漏了什么吗?还是有不允许这样做的原因?

// the class declaration
class MapImage : public MapEntity, public Vector2D {};

// the variable declaration
std::vector<MapImage> healthpacks;

// the function
void DrawItems(SDL_Surface *dest, std::vector<Vector2D> &items, SDL_Surface *image);

// the implementation
DrawItems(dest, healthpacks, healthpack_image);

由于 healthpacks 是 MapImage 类的 std::vector,并且 MapImage 具有基类 Vector2D,因此“std::vector healthpacks”不应与“std::vector &items”兼容,因为它们具有相同的基类?

【问题讨论】:

  • 是的。你得到什么编译错误?
  • 使用 <或反引号,这样您的 vector 就不会在问题文本中被错误解析( 被隐藏)。

标签: c++ class inheritance vector arguments


【解决方案1】:

没有。基类向量本身并不是派生类向量的基类。

考虑如果DrawItems 将一个Vector2D 对象(一个不是 MapImage 的对象)插入到项目中:你会在vector 中拥有一个不是MapImage 的东西。但是,由于 DrawItems 有一个矢量,从它的角度来看,该插入将是完全有效的。

相反,在迭代器上传递迭代器范围和模板:

void DrawItem(SDL_Surface *dest, Vector2D &item, SDL_Surface *image);

template<class Iter>
void DrawItems(SDL_Surface *dest, Iter begin, Iter end, SDL_Surface *image) {
  for (; begin != end; ++begin) {
    DrawItem(dest, *begin, image);
  }
}

或者在容器上:

template<class Container>
void DrawItems(SDL_Surface *dest, Container &items, SDL_Surface *image) {
  typename Container::iterator begin = items.begin(), end = items.end();
  for (; begin != end; ++begin) {
    DrawItem(dest, *begin, image);
  }
}

或者,完全不用 DrawItems,但仍然使用我上面声明的 DrawItem,也许使用新奇的 for-each 循环:

// this: DrawItems(dest, healthpacks, healthpack_image);
// becomes:
for (auto &x : healthpack) DrawItem(dest, x, healthpack_image);

您似乎还需要添加 const,但我已经按照您的方式保留了代码。

【讨论】:

    【解决方案2】:

    嗯,不。

    当然你可以从 MapImage 向上转换为 Vector2D,但 vector 是不相关的类型。 您期待直接案例还是创建副本?后者不会发生,因为对 vector.

    的非常量引用

    为什么?支持这些只是数组,迭代器需要知道记录的大小,这对于不同的类型会有所不同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多