我遇到了一个有趣的错误,我很确定它与条件语句的上下文中的包含多态性有关.
该示例的亮点如下:
ClassParent *parentPointer; //Declare pointer to parent if(condition){ ClassChild1 = mychild; //Declare child1 object parentPointer = *mychild;//Parent pointer points to child } if(!condition){ ClassChild2 = mychild; //Declare child2 parentPointer = *mychild;//Parent pointer points to child2 } cout << *parentPointer; //What will this point to???
应该清楚,条件语句在最后一行中生成*parentPointer变量.
我的整个函数看起来像这样:(注意崩溃的地方)
void PosApp::addItem(bool isPerishable) { Item *refitem; if (isPerishable) { Perishable myitem; std::cout << "Enter the following: " << std::endl << "Sku: " << std::endl << "Name:" << std::endl << "Price: " << std::endl << "Taxed: " << std::endl << "Quantity: " << std::endl << "Expiry date: " << std::endl; std::cin >> myitem; refitem = &myitem; //Item now implements inclusion polymorphism, be aware of dynamic/static types (dynamic is item, static Perishable) } if (!isPerishable) { NonPerishable myitem; std::cout << "Enter the following: " << std::endl << "Sku: " << std::endl << "Name:" << std::endl << "Price: " << std::endl << "Taxed: " << std::endl << "Quantity: " << std::endl; std::cin >> myitem; refitem = &myitem; //Item now implements inclusion polymorphism, be aware of dynamic/static types (dynamic is item, static NonPerishable) } if (cin.fail()) {//The inclusion polymorphism allows me to call this block only once regardless of persh/non-perishable cin.clear(); cin.ignore(2000, '\n'); //CRASH POINT*********** cout << "Error: " << *refitem << endl;//Be aware of early/late binding, the write/dowrite must be child calls, not parent. } }
现在非常有趣的是,当删除cin.fail上的if()并强制输入错误时,它可以工作.代码现在看起来像这样:
void PosApp::addItem(bool isPerishable) { Item *refitem; if (!isPerishable) { NonPerishable myitem; std::cout << "Enter the following: " << std::endl << "Sku: " << std::endl << "Name:" << std::endl << "Price: " << std::endl << "Taxed: " << std::endl << "Quantity: " << std::endl; std::cin >> myitem; refitem = &myitem; //Item now implements inclusion polymorphism, be aware of dynamic/static types (dynamic is item, static NonPerishable) cin.clear(); cin.ignore(2000, '\n'); //THIS DOES NOT CRASH NOW cout << "Error: " << *refitem << endl;//Be aware of early/late binding, the write/dowrite must be child calls, not parent. }
就崩溃而言,我能想出的最佳答案是,在第一个代码片段中解析范围时,程序丢失了指针的内容.
这个问题有两个问题:你可以在条件语境中实现包含多态性(如图所示),如果不是,这是导致程序崩溃的原因吗?
注意:我没有包含整个程序(因为它是数百行),但足以说,当我将代码更改为第二个代码段时,行为应该是预期的.
具有自动存储的对象是{ }
它们周围的括号的本地对象,包括if
语句.如果您有一个指向本地的指针,并且该对象超出范围,则访问该指针的是UB.
Object* ptr; if (condition) { Object obj; ptr = &obj; } //obj is out of scope *ptr; //undefined behaviour
这是您在设置refitem
指向本地对象时所做的事情.相反,创建一个Perishable*
或NonPerishable*
通过使用new
,当块结束时,将指针指定给refitem
.多态性将按预期工作,错误只是对象的范围.
if (!isPerishable) { NonPerishable* myitem = new NonPerishable(); //dynamic memory std::cin >> *myitem; refitem = myitem; //refitem is still valid after this scope ends }