如何构造一个可以替换子类然后再进行泛型调用的模板类类型?

时间:2019-05-02 16:27:48

标签: c++ templates

我有10种硬币类型:BTC,ETH,Shift等。为此,我有一个超类“硬币”和每个硬币的子类。然后,我有一个指向“硬币”类型的指针,这样无论它们是什么子类型,我都可以调用它们。

问题是,我只知道如何用Java而不是C ++来做到这一点。我很难找到正确的术语,因为除了“泛型”之外,我真的不知道该搜索什么。我想要的是这样的:

// Superclass
class Coin {
public:
    virtual void handleCoin();
};


// Subclass
class BTC: public Coin {
    void handleCoin();
}

BTC::BTC() = default;
BTC::~BTC() = default;

BTC::handleCoin() {
    std::cout << "handling BTC" << std::endl;
}


// Subclass
class ETH: public Coin {
    void handleCoin();
}

ETH::ETH() = default;
ETH::~ETH() = default;

ETH::handleCoin() {
    std::cout << "handling ETH" << std::endl;
}


// Execute
int main() {
    Coin* coin;
    coin = BTC();
    coin.handleCoin();
    coin = ETH();
    coin.handleCoin();
    return 0;
}

我要打印:

handling BTC
handling ETH

我知道我需要使用模板,但是找不到这种特定情况的具体示例。

此外,我的构造函数不接受参数,所以我想我的模板声明应该是

template<>

但是我看到的所有示例都可以使用

template<typename T>

然后将T类型用作函数参数,例如调用

max<float, float>
max<double, double>

但这不是我想要的。有没有办法将上面的示例转换为可工作的C ++代码?

1 个答案:

答案 0 :(得分:2)

从发布的代码中我看不到需要模板,虚拟方法无需模板即可工作。要在主代码中修复代码,您需要使用指针/引用,并且还具有虚拟析构函数。

class Coin {
public:
    virtual void handleCoin();
    virtual ~Coin()=default;
};
class BTC: public Coin {
public:
    BTC::BTC() = default;
    //Destructor of a derived class is automatically virtual if the base class's one is.
    void handleCoin();
}

// Subclass
class ETH: public Coin {
    void handleCoin();
    ETH::ETH() = default;
    //Still virtual even if you specify otherwise
    ETH::~ETH() = default;
}
int main() {
    Coin* coin;
    coin = new BTC();//Returns BTC*   <--pointer

    coin->handleCoin();
    delete coin;//Calls Coin::~Coin() -> thus the need for virtual so BTC::~BTC is called instead.
    coin = new ETH();
    coin->handleCoin();
    delete coin;//Same, calls ETH::~ETH()
    return 0;
}

手动内存管理容易出错,从C ++ 11开始,有一种更好的方法应被强烈推荐:

int main() {
    std::unique_ptr<Coin> coin;//Hides the pointer, but still has pointer-like semantics
    coin = std::make_unique<BTC>();
    coin->handleCoin();
    //Automatically frees old memory
    coin = std::make_unique<BTC>();
    coin->handleCoin();
    //Calls unique ptr's dtor because coin is local variable, which again frees the memory correctly.
    return 0;
}