未调用覆盖的虚拟方法

Lai*_*aif 3 c++

在下面的代码中,我试图覆盖price()Taxed 和 Untaxed的函数,但是,它们都调用父虚拟函数而不是提供给它们的覆盖函数。我搞砸了什么?

头文件:

#ifndef PRODUCT_H
#define PRODUCT_H
#include <string>
#include <iostream>

class Product {

protected:
    int _quantity;
    double _cost;
    std::string _name;

public:
    Product(std::string name, double cost);

    virtual ~Product();

    void set_quantity(int quantity);

    virtual double price() const;

    friend std::ostream & operator<< (std::ostream &ost, const Product &product);
};

std::ostream & operator<< (std::ostream &ost, const Product &product);

class Taxed : public Product{

private:
    static double _tax;

public:
    using Product::Product;

    virtual ~Taxed();

    static void set_tax_rate(double sales_tax);

    double price() const override;
};

class Taxfree : public Product{
public:
    using Product::Product;

    virtual ~Taxfree();

    double price() const override;
};


#endif //PRODUCT_H

Run Code Online (Sandbox Code Playgroud)

.cpp 文件:

#include <string>
#include <iomanip>
#include <iostream>
#include "product.h"

Product::Product(std::string name, double cost){
    _name = name;
    _cost = cost;
    _quantity = NULL;
};

Product::~Product(){};

void Product::set_quantity(int quantity){
    if (quantity < 0){
        std::cerr << "Cannot have negative quantity";
    }
    _quantity = quantity;
};

double Product::price() const {
    return 2;
};

std::ostream & operator<< (std::ostream &ost, const Product &product){
    if (product._quantity > 0)
        ost << product._name << " (" << product._quantity << " @ " << std::fixed << std::setprecision(2) << std::setfill('0') << product.price() << ")";
    else
        ost << product._name << " (" << std::fixed << std::setprecision(2) << std::setfill('0') << product.price() << ")";

    return ost;
};

double Taxed::_tax = 0.0825;

Taxed::~Taxed(){};

void Taxed::set_tax_rate(double sales_tax) {
    Taxed::_tax = sales_tax;
};

double Taxed::price() const{
    return _quantity * _cost * (1+_tax);
}


Taxfree::~Taxfree(){};

double Taxfree::price() const{
    return _quantity * _cost;
}
Run Code Online (Sandbox Code Playgroud)

jtb*_*des 9

您正在体验对象切片。通过存储 a std::vector<Product>,您实际上是在创建基本 Product 类的实例并丢失 Taxed 和 Taxfree 的实例。在 中products.push_back(Taxfree("Apple", 2)),Taxfree 被传递给编译器生成的复制构造函数Product(const Product&),因为Taxfree对象可以绑定到const Product&.

假如你删除的基本实现price(),并使它成为纯虚函数virtual double price() const = 0;,你会注意到这个问题,当你的程序无法编译(因为产品会成为一个抽象类,建设将不再是可能的)。

相反,您将需要使用以下内容std::vector<std::shared_ptr<Product>>

std::vector<std::shared_ptr<Product>> products;
products.push_back(std::make_shared<Taxfree>("Apple", 2));
products.push_back(std::make_shared<Taxed>("Iron",1.75));
products.push_back(std::make_shared<Taxfree>("Soda",2.5));
products.push_back(std::make_shared<Taxfree>("Lemon",2.5));
Run Code Online (Sandbox Code Playgroud)

(我建议unique_ptr改为,但看起来您希望productscart包含相同的对象。或者,您可以使用unique_ptr并仅创建产品的副本,如果您打算对它们进行变异,这可能会更好。)