gpt4 book ai didi

c++ - 模板还是抽象基类?

转载 作者:IT老高 更新时间:2023-10-28 12:31:48 29 4
gpt4 key购买 nike

如果我想让一个类具有适应性,并且可以从外部选择不同的算法——C++ 中最好的实现是什么?

我主要看到两种可能性:

  • 使用抽象基类并传入具体对象
  • 使用模板

这是一个小例子,在不同的版本中实现:

版本 1: 抽象基类

class Brake {
public: virtual void stopCar() = 0;
};

class BrakeWithABS : public Brake {
public: void stopCar() { ... }
};

class Car {
Brake* _brake;
public:
Car(Brake* brake) : _brake(brake) { brake->stopCar(); }
};

版本 2a: 模板

template<class Brake>
class Car {
Brake brake;
public:
Car(){ brake.stopCar(); }
};

版本 2b: 模板和私有(private)继承

template<class Brake>
class Car : private Brake {
using Brake::stopCar;
public:
Car(){ stopCar(); }
};

来自 Java,我自然倾向于始终使用版本 1,但模板版本似乎更受欢迎,例如在 STL 代码中?如果这是真的,仅仅是因为内存效率等(没有继承,没有虚函数调用)吗?

我知道版本 2a 和 2b 之间没有太大区别,请参阅 C++ FAQ .

您能评论一下这些可能性吗?

最佳答案

这取决于您的目标。如果你可以使用版本 1

  • 打算更换汽车的制动器(在运行时)
  • 打算将 Car 传递给非模板函数

我通常更喜欢使用运行时多态的版本 1,因为它仍然很灵活,并且允许您让 Car 仍然具有相同的类型:Car<Opel>Car<Nissan> 不同的类型.如果您的目标是在频繁使用刹车时表现出色,我建议您使用模板化方法。顺便说一下,这称为基于策略的设计。您提供刹车政策。例如,因为您说您使用 Java 编程,可能您对 C++ 还没有太多经验。一种方法:

template<typename Accelerator, typename Brakes>
class Car {
Accelerator accelerator;
Brakes brakes;

public:
void brake() {
brakes.brake();
}
}

如果您有很多策略,您可以将它们组合到它们自己的结构中,然后传递那个,例如作为 SpeedConfiguration收藏 Accelerator , Brakes还有更多。在我的项目中,我尝试保持大量代码无模板,允许它们一次编译到自己的目标文件中,而不需要它们的代码在头文件中,但仍然允许多态性(通过虚拟函数)。例如,您可能希望在基类中保留非模板代码可能会在很多情况下调用的通用数据和函数:

class VehicleBase {
protected:
std::string model;
std::string manufacturer;
// ...

public:
~VehicleBase() { }
virtual bool checkHealth() = 0;
};


template<typename Accelerator, typename Breaks>
class Car : public VehicleBase {
Accelerator accelerator;
Breaks breaks;
// ...

virtual bool checkHealth() { ... }
};

顺便说一句,这也是 C++ 流使用的方法:std::ios_base包含不依赖于字符类型或特征的标志和东西,如 openmode、格式标志和东西,而 std::basic_ios then 是一个继承它的类模板。这还通过共享类模板的所有实例所共有的代码来减少代码膨胀。

私有(private)继承?

一般应避免私有(private)继承。它很少有用,在大多数情况下,遏制是一个更好的主意。当大小非常重要时(例如基于策略的字符串类),通常情况正好相反:从空策略类(仅包含函数)派生时可以应用空基类优化。

阅读 Uses and abuses of Inheritance通过赫伯萨特。

关于c++ - 模板还是抽象基类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/602593/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com