C++ 无指针多态性
我试图创建一个抽象类,并使用它来确定购买的付款方式,使用多态性。我尝试了一些不同的方法,但是我仍然不能让它像我想要的那样工作。代码如下:C++ 无指针多态性,c++,polymorphism,C++,Polymorphism,我试图创建一个抽象类,并使用它来确定购买的付款方式,使用多态性。我尝试了一些不同的方法,但是我仍然不能让它像我想要的那样工作。代码如下: class PaymentMethod { public: PaymentMethod() {} virtual std::string getPaymentMethod() = 0; }; class PayWithMoney : public PaymentMethod { public:
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)
但我不断收到编译器错误消息,称无法将字段“Purchase::\u paymentMethod”声明为抽象类型“paymentMethod”
我猜我将不得不使用指针,对吗
我想我应该尽量避免new
和delete
,除非使用长寿命对象,但由于PaymentMethod
是一个抽象类,我不能将其用作类成员。。。我错了吗 你应该尽量避免新建
和删除
,这是绝对正确的
以下是方法:
#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>());
}
};
请注意,std::make_unique
还不存在,因此您可能不得不说:
return Purchase(std::unique_ptr<PaymentMethod>(new PayWithCash));
return-Purchase(标准::unique_ptr(新的现金支付));
这是您唯一需要说的new
,即使是在标准库中提供了std::make_unique
后,这一点也会消失
作为此设计的另一个好处,您现在可以轻松添加测试代码,例如模拟支付方法。您应该尽量避免新建
和删除
,这是绝对正确的
以下是方法:
#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>());
}
};
请注意,std::make_unique
还不存在,因此您可能不得不说:
return Purchase(std::unique_ptr<PaymentMethod>(new PayWithCash));
return-Purchase(标准::unique_ptr(新的现金支付));
这是您唯一需要说的new
,即使是在标准库中提供了std::make_unique
后,这一点也会消失
作为此设计的另一个好处,您现在可以轻松添加测试代码,例如模拟支付方法。只需从purchase类中删除
PaymentMethod\u PaymentMethod
,您的purchase
函数仍然会收到它
另一件事,由于您将常量引用传递给Purchase
,因此Purchase
调用的所有函数都必须是常量:
virtual std::string getPaymentMethod() = 0;
-->
只需从purchase类中删除
PaymentMethod\u PaymentMethod
,您的purchase
函数仍然会收到它
另一件事,由于您将常量引用传递给Purchase
,因此Purchase
调用的所有函数都必须是常量:
virtual std::string getPaymentMethod() = 0;
-->
将
\u paymentMethod
作为参考或指针。不过,您仍然需要考虑对象内存的生命周期。您的意思是PaymentMethod&\u PaymentMethod
?@Chowlett不是真的。只允许在开头加下划线,或在任何地方加双下划线。@Tim。是的,只在全局名称空间中保留。我坐正了。不过,这可能还是个坏主意。@msk:您可以使用构造函数中的初始值设定项列表来初始化引用。即ctor(ref&a):成员a(a){}代码>。如果您使用的是指针,您可以对其进行类似的初始化,只需将指针传递到构造函数中(通过new
返回或获取对象的地址)。如果您获取对象的地址或通过引用传递它,则需要注意它何时超出范围…将\u paymentMethod
设置为引用或指针。不过,您仍然需要考虑对象内存的生命周期。您的意思是PaymentMethod&\u PaymentMethod
?@Chowlett不是真的。只允许在开头加下划线,或在任何地方加双下划线。@Tim。是的,只在全局名称空间中保留。我坐正了。不过,这可能还是个坏主意。@msk:您可以使用构造函数中的初始值设定项列表来初始化引用。即ctor(ref&a):成员a(a){}代码>。如果您使用的是指针,您可以对其进行类似的初始化,只需将指针传递到构造函数中(通过new
返回或获取对象的地址)。如果您获取一个对象的地址或通过引用传递它,您需要注意它何时超出范围…在这种情况下,我不想使用智能指针,也不应该在我的应用程序中使用任何类型的静态内容code@msk您可以选择智能指针或指针,而智能指针更智能。你对static
关键字有宗教上的反对意见吗,或者你有其他理由不使用该关键字吗?我的老师不喜欢static关键字是我的理由。无论如何,我尝试了引用,但我不能,因为它不能在没有非专业化的情况下声明,所以我将尝试使用pointers@msk:私有构造函数和静态工厂函数只是实现它的一种方法。如果愿意,您可以公开构造函数,并手动传递付款方式。这是一个你想向谁公开多少的问题。在这种情况下,我真的不想使用智能指针,也不应该在我的系统中使用任何静态的东西code@msk您可以选择智能指针或指针,而智能指针更智能。你对static
关键字有宗教上的反对意见吗,或者你有其他理由不使用该关键字吗?我的老师不喜欢static关键字是我的理由。无论如何,我尝试了引用,但我不能,因为它不能在没有非专业化的情况下声明,所以我将尝试使用pointers@msk:私有构造函数和静态工厂函数只是实现它的一种方法。如果愿意,您可以公开构造函数,并手动传递付款方式。这是一个你想公开多少以及向谁公开的问题。我想存储PaymentMethod,因为我有一个稍后获取它的方法,这就是为什么我将它创建为类成员。然后你的选项是指针或引用。后者要求您在构造函数中设置它。我想存储PaymentMethod,因为我有一个方法可以稍后获取它,这就是为什么我将它创建为类成员。Th