Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 无指针多态性_C++_Polymorphism - Fatal编程技术网

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