gpt4 book ai didi

c++ - 使用不同的实现文件来实现多态是不是可以?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:35:10 27 4
gpt4 key购买 nike

如果给定接口(interface)有多个所需的实现,但所需的具体实现在编译时就已知,那么简单地将 make 文件定向到同一 header 的不同实现文件是否错误?

例如,如果有一个定义汽车的程序(Car.h)

// Car.h
class Car {
public:
string WhatCarAmI();
}

并且在构建时我们知道我们想要它是法拉利还是菲亚特,给每个相应的文件:

// Ferrari.cpp
#include "Car.h"
string Car::WhatCarAmI() { return "Ferrari"; }

而对于另一种情况(不出所料)

// Fiat.cpp
#include "Car.h"
string Car::WhatCarAmI() { return "Fiat"; }

现在,我知道我可以制作 Car 的 Fiat 和 Ferrari 派生对象,并在运行时选择我想要构建的对象。同样,我可以将其模板化并让编译器在编译时选择要构建的内容。然而,在这种情况下,这两个实现都引用了不应该交叉的独立项目。

鉴于此,执行我的建议并简单地在给定项目的 makefile 中选择正确的 .cpp 是错误的吗?执行此操作的最佳方法是什么?

最佳答案

实现

由于这是静态多态性,奇怪的重复模板模式可能比交换 cpp 文件更惯用 - 这看起来很老套。如果您想让多个实现在一个项目中共存,同时又易于与强制的单一实现构建系统一起使用,那么 CRTP 似乎是必需的。我想说它有据可查的性质和同时具备这两种能力(因为您永远不知道以后需要什么)给了它优势。

简而言之,CRTP 看起来有点像这样:

template<typename T_Derived>
class Car {
public:
std::string getName() const
{
// compile-time cast to derived - trivially inlined
return static_cast<T_Derived const *>(this)->getName();
}

// and same for other functions...
int getResult()
{
return static_cast<T_Derived *>(this)->getResult();
}

void playSoundEffect()
{
static_cast<T_Derived *>(this)->playSoundEffect();
}
};

class Fiat: public Car<Fiat> {
public:
// Shadow the base's function, which calls this:
std::string getName() const
{
return "Fiat";
}

int getResult()
{
// Do cool stuff in your car
return 42;
}

void playSoundEffect()
{
std::cout << "varooooooom" << std::endl;
}
};

(我之前用d_作为派生实现函数的前缀,但我不确定这有什么好处;事实上,它可能会增加歧义...)

要了解 CRTP 中真正发生的事情 - 一旦掌握就很简单! - 周围有很多指南。您可能会发现很多变体,然后选择您最喜欢的一个。

编译时选择实现

回到另一方面,如果您确实想在编译时限制其中一个实现,那么您可以使用一些预处理器宏来强制执行派生类型,例如:

g++ -DMY_CAR_TYPE=Fiat

以后

// #include "see_below.hpp"
#include <iostream>

int main(int, char**)
{
Car<MY_CAR_TYPE> myCar;

// Do stuff with your car
std::cout << myCar.getName();
myCar.playSoundEffect();
return myCar.getResult();
}

您可以在单个 header 和#include 中声明所有 Car 变体,或者使用类似这些线程中讨论的方法 - Generate include file name in a macro/Dynamic #include based on macro definition - 从相同的 -D 宏生成 #include

关于c++ - 使用不同的实现文件来实现多态是不是可以?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36695268/

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