如何子类化模板化的基类?

Bri*_*ian 6 c++ inheritance templates

我有以下数据结构:

struct fastEngine { ... }
struct slowEngine { ... }

template<typename T>
class Car {
   T engine;
   vector<T> backupEngines;

   virtual void drive() = 0;
}

class FastCar : public Car<fastEngine> {
   virtual void drive() {
      // use the values of "engine" in some way
   }
}

class SlowCar : public Car<slowEngine> {
   virtual void drive() {
      // use the values of "engine" in some way
   }
}

Car* getCarFromCarFactory() {  // 1
   if (randomNumber == 0)
      return new FastCar();
   else
      return new SlowCar();
}

void main() {
   Car* myCar = getCarFromCarFactory(); // 2
   myCar->drive();
}
Run Code Online (Sandbox Code Playgroud)

编译器在位置1和2处抱怨,因为它要求我使用模板参数定义Car*.我不在乎我正在使用的汽车模板版本,我只想要一个可以开车的汽车指针.该发动机的结构必须是结构,因为他们是从现有的代码,我没有对它们的控制.

Cat*_*lus 16

您可以创建一个Car<T>继承的非模板化基类,例如

struct ICar {
    virtual void drive() = 0;
};

template <typename T>
class Car : public ICar {
    // ...
}

int main() { // BTW, it's always `int main`, not `void main`
    ICar *myCar = getCarFromCarFactory();
    myCar->drive();
}
Run Code Online (Sandbox Code Playgroud)

  • @codetaku这不是"意见",它是标准所要求的(与其中的返回不同,显式默认返回0). (3认同)
  • @codetaku如果我告诉你`返回0;``main`中的`在C++中是可选的,并且需要`int main()`怎么办? (3认同)
  • @codetaku`int main`是标准所要求的.在OP的情况下,`void main`完全编译的事实是,IMO,编译器的缺陷. (3认同)

Éri*_*ant 5

PiotrLegnica 的回答是对的,但我想补充几点:

类模板不是类

在您的代码中, Car 是一个类模板。类模板不是类,它只是……可以定义类的模板,同一个模板的不同实例不一定会导致类型具有相同的接口。一个简单的例子:

template<class T>
class Foo
{
public:
  T Bar();
  bool Baz(const T&);
};
Run Code Online (Sandbox Code Playgroud)

struct 和 class 是(几乎)相同的东西

引擎结构必须是结构,因为它们来自现有代码,我无法控制它们。

我假设你写这个是因为你怀疑这个问题与使用结构而不是类作为模板参数有关。不是这种情况。在 C++ 中,struct 和 class 几乎是一回事。唯一的区别是默认访问和继承对于结构是公共的,而对于类是私有的。