使用C++模板创建具有自定义组件的类

Nat*_*han 2 c++ templates

让我通过一个例子来解释我所要求的内容.想象一下,我有一个汽车课.现在,汽车可能有很多额外的东西:

  • 4门而不是2门
  • 自动门锁
  • 4轮驱动

我想用这些选项的任意组合创建类.任何这些选项都需要一些数据成员.想象一下这个班级现在看起来像这样:

class Car {
public:
  bool FourDoors;
  bool AutomaticDoorLocking;
  bool FourWheelDrive;

  Door doors[4];  //4 only needed if FourDoors=true
  DoorLockingElectronic doorElectronic; //Only needed if AutomaticDoorLocking=true
  TransmissionsShafts[4]; //4 only needed for FourWheelDrive=true

  void lockDoors() {
    if (AutomaticDoorLocking) {
      doorElectronic.lockDoors();
    } else {
      // Do manual door locking
    }
  }
};
Run Code Online (Sandbox Code Playgroud)

到目前为止一切都那么好,但是现在我想创造很多车,这么多内存变得至关重要.而且我不需要大多数汽车的大部分额外功能.我可以创建一个基类,并派生启用或禁用这些选项的类.但我必须创建2 ^ {#extras}类来创建所有可能的组合,并使用大量的双重代码.

所以我想也许可以使用模板?(就是那个问题).

我可以想象有一个标志模板,并像这样重写lockDoors:

template<int flags>
void Car<flags>::lockDoors() {
  if (flags | AutomicDoorLockingFlag) {
    doorElectronic.lockDoors();
  } else {
    // Do manual door locking
  }
}
Run Code Online (Sandbox Code Playgroud)

精彩!但是Car <0>类仍然需要很多不必要的空间.所以:

我可以根据模板参数以某种方式包含或排除类成员吗?

其他想法如何应对这种情况也欢迎!

Pet*_*der 6

您想要使用策略类:

class FourDoorPolicy { Door m_doors[4]; ... };
class TwoDoorPolicy { Door m_doors[2]; ... };

class AutoDoorLockingPolicy { ... };
class ManualDoorLockingPolicy { void lockDoors(); ... };

class FourWheelDrivePolicy { TransmissionShafts m_shafts[4]; ... };
class TwoWheelDrivePolicy { TransmissionShafts m_shafts[2]; ... };

template <class DoorPolicy = TwoDoorPolicy,
          class LockingPolicy = ManualDoorLockingPolicy,
          class DrivePolicy = TwoWheelDrivePolicy>
class Car : public DoorPolicy, public LockingPolicy, public DrivePolicy
{
  ...
};
Run Code Online (Sandbox Code Playgroud)

将所有特定于策略的内容(例如lockDoors()函数)放在策略类而不是Car类中.在Car类继承这些,这是组成的形式(即你正在建设自己的所有功能,入Car类).

请注意,您应该为所有策略类提供protected非virtual析构函数,以便它们只能作为派生类的一部分进行实例化.

然后,您以常规模板方式实例化自定义汽车:

Car<FourDoorPolicy, AutoDoorLockingPolicy, TwoWheelDrivePolicy> myCar;
Run Code Online (Sandbox Code Playgroud)

当然,您可以使用typedefs来帮助解决这个问题(C++ 0x中的模板别名也会有很大帮助).

请参阅:基于策略的设计