Reputation: 139
I was trying to create an abstract class and use it to determine the paying method of a purchase, using polymorphism. I tried some different things, but I can't still get it to work as I wanted. Here is the code:
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;
}
};
And I have another class:
class Purchase {
private:
something
PaymentMethod _paymentMethod;
public:
Purchase(something, const PaymentMethod& paymentMethod)
But I keep getting compiler error saying cannot declare field ‘Purchase::_paymentMethod’ to be of abstract type ‘PaymentMethod’
.
I'm guessing I will have to use pointers instead right?
I thought I should try to avoid new
and delete
unless working with long-lived objects, but since PaymentMethod
is an abstract class, I can't use it as a class member... Am I wrong?
Upvotes: 1
Views: 546
Reputation: 476990
You should try to avoid new
and delete
, that's absolutely correct.
Here's how:
#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>());
}
};
Usage:
auto purchase = Purchase::MakeCashPurchase();
Note that std::make_unique
doesn't exist yet, so you may instead have to say:
return Purchase(std::unique_ptr<PaymentMethod>(new PayWithCash));
This is the only time you have to say new
, and even that will go away once std::make_unique
is available in the standard library.
As an added benefit of this design, you can now easily add testing code, such as mock payment methods.
Upvotes: 5
Reputation: 7960
Just remove PaymentMethod _paymentMethod
from the purchase class, your Purchase
function receives it anyway.
Another thing, since you pass a const reference to Purchase
, all the functions that Purchase
calls must be const:
virtual std::string getPaymentMethod() = 0;
-->
virtual std::string getPaymentMethod() const = 0;
Upvotes: 0