在下面的代码中,我试图覆盖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)
您正在体验对象切片。通过存储 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改为,但看起来您希望products和cart包含相同的对象。或者,您可以使用unique_ptr并仅创建产品的副本,如果您打算对它们进行变异,这可能会更好。)