我正在尝试构建一个“糖果店用户界面”,我有 4 个类:
SweetItem 类 - 抽象基类
Candy、Cookie、IceCream 类 - 几乎从基类派生
Cookielida - 派生自 cookies 类和冰淇淋类
现在我在基类中有:
class SweetItem
{
public:
/*=====Builders & Destructor & = Operator=====*/
SweetItem();
SweetItem(const SweetItem&);
~SweetItem();
const SweetItem& operator=(const SweetItem&);
/*=====Input\Output operators=====*/
friend ostream& operator<<(ostream&, const SweetItem&);
friend istream& operator>>(istream&, SweetItem&);
/*=====Static members=====*/
static void NoSweets() { cout << num_sweets; }
static int get_num() { return num_sweets; }
/*=====Virtual Interface=====*/
virtual SweetItem* clone() const = 0;
virtual SweetItem* enter() = 0;
virtual void print() const = 0;
virtual int get_amount() const =0;
virtual float get_price() const = 0;
virtual String get_type() const = 0;
virtual float get_total() const = 0;
/*=====Cyber Function=====*/
void color(const int) const;
protected:
private:
static int num_sweets;
};
输入/输出正在调用虚函数“enter()”和“print()”:
ostream& operator<<(ostream& op, const SweetItem& input) {
if(&input)
input.print();
return op;
}
istream& operator>>(istream& ip, SweetItem& input) {
input.enter();
return ip;
}
当我尝试像这样使用 cookielida 的“enter()”时:
int main() {
SweetItem* temp = new Cookielida;
cin >> *temp;
cout << *temp << endl;
}
它打印我设置的默认对象而不是用户输入的选择。这是虚拟实现:
SweetItem* Cookielida::enter() {
String ct, it;
float cp, ip;
cout << "Please select from the available options: " << endl;
cout << "1) Butter cookies " << BUTTERP << "$ per unit" << endl;
cout << "2) Chocolate chip cookies " << CHIPP << "$ per unit" << endl;
cout << "3) Oreo cookies " << OREOP << "$ per unit" << endl;
int opt1;
opt1 = error(1, 3);
switch (opt1)
{
case BUTTER: ct = "Butter cookies";
cp = BUTTERP;
break;
case CHIP: ct = "Chocolate chip cookies";
cp = CHIPP;
break;
case OREO: ct = "Oreo cookies";
cp = OREOP;
break;
default:
break;
}
cout << "Please select from the available options: " << endl;
cout << "1) Vanilla icecream " << VANIP << "$ per unit" << endl;
cout << "2) Chocolate icecream " << CHOCP << "$ per unit" << endl;
cout << "3) Yogurt icecream " << YOGUP << "$ per unit" << endl;
int opt2;
opt2 = error(1, 3);
switch (opt2)
{
case VANI: it = "Vanilla icecream";
ip = VANIP;
break;
case CHOC: it = "Chocolate icecream";
ip = CHOCP;
break;
case YOGU: it = "Yogurt icecream";
ip = YOGUP;
break;
default:
break;
}
cout << "How many cookielidas do you want? " << endl;
int a;
a = error(0, MAXAMOUNT);
SweetItem* temp = new Cookielida(a, ip, cp, it, ct);
return temp;
}
我认为问题是在“enter()”函数中创建的临时 cookielida 被销毁而不是复制到“main()”中的临时文件。 这些也是构造函数:
Cookielida::Cookielida(int a=0, float ip=0, float cp=0, const String& it="", const String& ct="") :
IceCream(ICEA, ip, it), Cookie(COKA, cp, ct), amount(a), price((ip + cp * 2)*1.5), type(ct + " " + it)
{
}
Cookielida::Cookielida(const Cookielida& input) :
IceCream(ICEA, input.get_ip(), input.get_it()),
Cookie(COKA, input.get_cp(), input.get_ct()),
amount(input.amount), price(input.price), type(input.type)
{
}
这是输出:
最佳答案
问题出在您的 enter()
函数中。它不会改变对象本身,而是创建一个通过指针返回的新对象。因此,当您在 operator>>
重载中调用 input.enter();
时,input
所指的类不会发生变化——并且在事实上,没有任何事情发生,因为您返回的指针根本没有被使用。
作为解决方法,您可以执行以下操作
Cookielida& Cookielida::enter() //better return the derived object in a covariant way,
//not the base class pointer
//you can still downcast it if required
{
//read in those many parameters
//then either set the class member variables "a, ip, cp, it, ct"
//directly (--the preferred way)
//or use this cheap alternative
operator=(Cookielida(a, ip, cp, it, ct));
return *this;
}
关于C++ 用抽象类重载输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30373516/