没有指针的多态性

Polymorphism without pointers

本文关键字:多态性 指针      更新时间:2023-10-16

我试图创建一个抽象类,并使用多态性来确定购买的付款方式。我尝试了一些不同的东西,但我仍然无法让它按照我想要的方式工作。这是代码:

class PaymentMethod {
    public:
        PaymentMethod() {}
        virtual std::string getPaymentMethod() = 0;
};
class PayWithMoney : public PaymentMethod {
    public:
        PayWithMoney() {}
        virtual std::string getPaymentMethod() {
            std::string paymentMethod = "Payed with Money"; 
            return paymentMethod;
        }
};
class PayWithDebitCard : public PaymentMethod {
    public:
        PayWithDebitCard() {}
        virtual std::string getPaymentMethod() {
            std::string paymentMethod = "Payed with Debit Card"; 
            return paymentMethod;
        }
};

我还有另一堂课:

class Purchase {
    private:
        something
        PaymentMethod _paymentMethod;
    public:
        Purchase(something, const PaymentMethod& paymentMethod)

但是我不断收到编译器错误,说cannot declare field ‘Purchase::_paymentMethod’ to be of abstract type ‘PaymentMethod’.

猜我将不得不使用指针,对吧?

我认为我应该尽量避免newdelete,除非使用长寿命的对象,但由于PaymentMethod是一个抽象类,我不能将其用作类成员......我错了吗?

你应该尽量避免newdelete,这是绝对正确的。

方法如下:

#include <memory>       // for std::unique_ptr
#include <utility>      // for std::move
class Purchase
{
    Purchase(std::unique_ptr<PaymentMethod> payment_method)
    : payment_method_(std::move(payment_method))
    { }
    std::unique_ptr<PaymentMethod> payment_method_;
public:
    static Purchase MakeDebitCardPurchase()
    {
        return Purchase(std::make_unique<PayWithDebitCard>());
    }
    static Purchase MakeCashPurchase()
    {
        return Purchase(std::make_unique<PayWithCash>());
    }
};

用法:

auto purchase = Purchase::MakeCashPurchase();

请注意,std::make_unique尚不存在,因此您可能不得不说:

return Purchase(std::unique_ptr<PaymentMethod>(new PayWithCash));

这是您唯一必须说new ,一旦标准库中std::make_unique可用,即使这样也会消失。

作为此设计的另一个好处,您现在可以轻松添加测试代码,例如模拟付款方式。

只需从购买类中删除PaymentMethod _paymentMethod,您的Purchase函数无论如何都会收到它。

另一件事,由于您将 const 引用传递给 PurchasePurchase调用的所有函数都必须是 const:

virtual std::string getPaymentMethod() = 0;
-

->

virtual std::string getPaymentMethod() const = 0;