没有指针的多态性

msk*_*msk 1 c++ polymorphism

我试图创建一个抽象类,并使用它来确定购买的付费方式,使用多态.我尝试了一些不同的东西,但我还是不能按照我的意愿让它工作.这是代码:

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;
        }
};
Run Code Online (Sandbox Code Playgroud)

我有另一堂课:

class Purchase {
    private:
        something
        PaymentMethod _paymentMethod;
    public:
        Purchase(something, const PaymentMethod& paymentMethod)
Run Code Online (Sandbox Code Playgroud)

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

我猜我必须使用指针而不是正确吗?

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

Ker*_* SB 5

应该尽量避免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>());
    }
};
Run Code Online (Sandbox Code Playgroud)

用法:

auto purchase = Purchase::MakeCashPurchase();
Run Code Online (Sandbox Code Playgroud)

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

return Purchase(std::unique_ptr<PaymentMethod>(new PayWithCash));
Run Code Online (Sandbox Code Playgroud)

这是你必须说的唯一一次new,甚至一旦std::make_unique标准库中出现这种情况就会消失.

作为此设计的额外好处,您现在可以轻松添加测试代码,例如模拟支付方法.