类继承C++
我有一个基类产品和子类multiBuyProduct类继承C++
class Product
{
public:
Product(std::string name, Amount price);
}
class MultiBuyProduct :public Product
{
public:
MultiBuyProduct(std::string aName, Amount price, int minDiscountedQuantity, int discountedPercent);
现在显然有些构造函数的变量是相同的,但在我的主类我认为,如果我想multiBuyProduct的我所需要的功能打电话给它?或者我可以调用产品并将multiBuyProduct构造函数的值传递给期望产品的参数?
下面显示了这是用来
void ShoppingCart::add(Product p, int quantity, bool end)
{
}
以上就是我要发送的参数,但我不知道我是否需要更改代码,这个方法接受一个MultiBuyProduct或方法的方法。 ??
编辑:对不起,忘了提“金额”是一类,它有两个整数
Amount amount(0,1);
你应该改变ShoppingCart::add
类似下面,实现多态行为:
void ShoppingCart::add(Product *p, int quantity, bool end)
{
p->doSomething();
// ...
Product *product = p;
product->doSomething();
// ...
}
用法:
ShoppingCart shoppingCart;
MultiBuyProduct multiBuyProduct("Paper", Amount(0,1), 1, 1);
shoppingCart.add(&multiBuyProduct, 1, true);
你可能会想在Product
添加virtual
方法,比方说,Amount Product::calculatePrice(int quantity)
,并在MultiBuyProduct
覆盖它,以便它会根据minDiscountedQuantity
执行正确的计算。然后,从add()
调用此方法。此外,您需要将参考(Product&
)或指针(Product*
)传递到add()
以便虚拟方法调用起作用。
感谢,但我真的不知道不足以真正明白,我将发布更多的代码? – AngryDuck 2013-03-11 09:29:52
@AngryDuck:虚拟方法的解释对于这篇文章来说太长了,所以你需要阅读它。然而,核心思想是,当你在基类中有一个虚拟方法时,子类可以用自己的代码替换该方法,这样子类中的行为就会不同。如果你有一个指向'Product'的指针并且调用一个虚拟方法,C++将会找出指针指向的对象类型,并调用正确的方法(所以即使你不知道你实际上有一个'MultiBuyProduct',你会得到正确的价格计算)。 – 2013-03-11 09:59:00
不错的一个感谢小解释我现在得到它,我只是不清楚的c + +术语,它基本上是c + +的方式,只是用@override标记覆盖java中的方法:P – AngryDuck 2013-03-11 10:05:06
你应该改变一些事情。
您需要一种针对多态行为的指针或引用。
您需要调用基类构造函数。
你需要覆盖你的虚拟方法。
一旦你依赖指针,你应该留意正确的内存管理。您可以尝试成为const correct。
考虑下面这个例子:
#include <string>
#include <iostream>
#include <vector>
#include <memory>
#include <sstream>
class Product
{
private:
double Price;
std::string Name;
public:
Product(const std::string& name, double price)
: Price(price),
Name(name)
{
std::cout << "Created " << name << " for $" << price << std::endl;
}
virtual std::string GetName() const
{
return Name;
}
virtual double GetPrice() const
{
return Price;
}
};
class MultiProduct :public Product
{
private:
int Quantity;
public:
MultiProduct(const std::string& name, double price, int quantity)
: Product(name, price),
Quantity(quantity)
{
std::cout << "Created " << quantity << "x " << name << " for $" << price << " each." << std::endl;
}
virtual double GetPrice() const
{
return Product::GetPrice() * Quantity;
}
virtual std::string GetName() const
{
std::stringstream s;
s << Product::GetName();
s << " x";
s << Quantity;
return s.str();
}
};
class ShoppingCart
{
private:
std::vector< std::shared_ptr<Product> > Cart;
public:
void Add(std::shared_ptr<Product> product)
{
Cart.push_back(product);
}
void PrintInvoice() const
{
std::cout << "Printing Invoice:" << std::endl;
for(auto it = Cart.begin() ; it != Cart.end() ; ++it)
{
std::cout << (*it)->GetName() << ": " << (*it)->GetPrice() << std::endl;;
}
}
};
int main()
{
ShoppingCart cart;
cart.Add(std::shared_ptr<Product>(new Product("cheese", 1.23)));
cart.Add(std::shared_ptr<Product>(new MultiProduct("bread", 2.33, 3)));
cart.Add(std::shared_ptr<Product>(new Product("butter", 3.21)));
cart.Add(std::shared_ptr<Product>(new MultiProduct("milk", 0.55, 5)));
cart.Add(std::shared_ptr<Product>(new Product("honey", 5.55)));
cart.PrintInvoice();
std::cout << "Press any key to continue" << std::endl;
std::cin.get();
return 0;
}
谢谢,但这真的没有建设性,我appriciate长时间的详细回复,但我不会像4个班级一样拆掉,当人们给出答案时,完全重制他们,这样做没有做到这一点 – AngryDuck 2013-03-11 09:57:22
好吧,如果你后来看似简单的解决方案遇到问题,请随时返回这里,并有一个在问一个新问题之前先看这个答案。其他答案看起来更简单,因为他们希望你已经知道他们的变化意味着你需要对你的程序进行其他修改。如果你不这样做,它迟早会崩溃。如果你这样做,最终会导致你所谓的撕裂4班。 – nvoigt 2013-03-11 10:08:52
谢谢你,但我的班级结构很好我有4个班,每个功能都有特定的用途,我想做的只是扩大产品的功能以便在购买一定数量的设备时增加折扣,我不认为这需要重写4班,我也不认为它公平地说在一个侮辱庄园的简单/容易的方式做以上这些答案只是更合适 – AngryDuck 2013-03-11 10:13:02
谢谢这看起来像我需要,iv做到这一点,但在我的方法添加,我如何使用p?即时贴产品产品= p;然后使用p.doSomething();例如,但它只是说我不能做产品= P;没有找到二元运算符? – AngryDuck 2013-03-11 09:35:08
需要确定产品产品= * p;现在没有错误,但是使用这种方法现在还没有返回任何东西。 product.getPrice();应该重新调整在main中传递的产品的价格,但是不做任何事情 – AngryDuck 2013-03-11 09:37:43
使用应该使用'p'这种方式:'p-> doSomething()'。 – deepmax 2013-03-11 09:38:21