Solidios Δημοσ. 18 Ιουνίου 2017 Δημοσ. 18 Ιουνίου 2017 (επεξεργασμένο) Το πρόγραμμα λύθηκε! Ευχαριστώ ολους. Επεξ/σία 18 Ιουνίου 2017 από Solidios
GReaperEx Δημοσ. 18 Ιουνίου 2017 Δημοσ. 18 Ιουνίου 2017 Ο πολυμορφισμός στη C++ δε λειτουργεί έτσι. Αν έχεις απλά αντικείμενα και αποθηκεύεις σε τύπο buildings, τότε οι αλλαγές που έγιναν στη θυγατρική κλάση δε πρόκειται να αποθηκευτούν. Πρέπει να χρησιμοποιήσεις δείκτες για να αποθηκεύσεις τα διάφορα buildings, με new και delete βέβαια. 2
Solidios Δημοσ. 18 Ιουνίου 2017 Μέλος Δημοσ. 18 Ιουνίου 2017 Δούλεψε σε ευχαριστώ πάρα πολυ! <3 , αλλα ο Vector γιατι crasharei ακομα; :/ Ο πολυμορφισμός στη C++ δε λειτουργεί έτσι. Αν έχεις απλά αντικείμενα και αποθηκεύεις σε τύπο buildings, τότε οι αλλαγές που έγιναν στη θυγατρική κλάση δε πρόκειται να αποθηκευτούν. Πρέπει να χρησιμοποιήσεις δείκτες για να αποθηκεύσεις τα διάφορα buildings, με new και delete βέβαια. Δούλεψε σε ευχαριστώ πάρα πολυ! <3 , αλλα ο Vector γιατι crasharei ακομα; :/
παπι Δημοσ. 18 Ιουνίου 2017 Δημοσ. 18 Ιουνίου 2017 1) κανε κοπιπειστνσε code tag. 2) https://www.visualstudio.com/vs/community/ 1
Moderators Kercyn Δημοσ. 18 Ιουνίου 2017 Moderators Δημοσ. 18 Ιουνίου 2017 Αυτό που θες, γενικά, γίνεται κάπως έτσι: enum class EType { Base, Derived }; class Base { public: Base() : Type(EType::Base), IntAttr(0) {} Base(int IntAttr_) : Type(EType::Base), IntAttr(IntAttr_) {} virtual ~Base() { std::cout << "Base destructor called." << std::endl; } EType GetType() const { return Type; } virtual void Print() const { std::cout << IntAttr << std::endl; } protected: EType Type; int IntAttr; }; class Derived final : public Base { public: Derived() : StrAttr("") { Type = EType::Derived; } Derived(std::string StrAttr_) : StrAttr(StrAttr_) { Type = EType::Derived; } ~Derived() override { std::cout << "Derived destructor called." << std::endl; } void Print() const override { std::cout << StrAttr << std::endl; } private: std::string StrAttr; }; int main(int argc, char* argv[]) { std::vector<std::unique_ptr<Base>> Container; Container.emplace_back(std::make_unique<Base>(5)); Container.emplace_back(std::make_unique<Derived>("aggouria")); Container.emplace_back(std::make_unique<Base>(75)); Container.emplace_back(std::make_unique<Derived>("ntomates")); Container.emplace_back(std::make_unique<Base>(18)); Container.emplace_back(std::make_unique<Derived>("karpouzia")); Container.emplace_back(std::make_unique<Base>(420)); Container.emplace_back(std::make_unique<Base>(9)); for (const auto& Class : Container) { if (Class->GetType() == EType::Derived) { static_cast<Derived*>(Class.get())->Print(); } else { Class->Print(); } } system("pause"); return 0; } Θα έχεις στη base class σου ένα enum όπου θα έχει τον τύπο της κλάσης σου. Στη συνέχεια όταν θες να δεις τον τύπο ενός object, σου αρκεί να συγκρίνεις το type που έχεις αποθηκεύσει. Αν λοιπόν ο τύπος του object που έχεις είναι Derived, κάνεις ένα static_cast για να πάρεις το derived type και καλείς όποια συνάρτηση της derived κλάσης θέλεις. Αν σε μπερδεύουν τα unique_ptr και στην τάξη έχετε κάνει μόνο "κανονικούς" pointers και new/delete κλπ, βάλε αυτά που έχετε μάθει (αν και "λάθος", δεν έχει τόση σημασία ακόμα, ειδικά αν δεν πολυνοιάζει και τον καθηγητή). 1
Solidios Δημοσ. 18 Ιουνίου 2017 Μέλος Δημοσ. 18 Ιουνίου 2017 Αυτό που θες, γενικά, γίνεται κάπως έτσι: enum class EType { Base, Derived }; class Base { public: Base() : Type(EType::Base), IntAttr(0) {} Base(int IntAttr_) : Type(EType::Base), IntAttr(IntAttr_) {} virtual ~Base() { std::cout << "Base destructor called." << std::endl; } EType GetType() const { return Type; } virtual void Print() const { std::cout << IntAttr << std::endl; } protected: EType Type; int IntAttr; }; class Derived final : public Base { public: Derived() : StrAttr("") { Type = EType::Derived; } Derived(std::string StrAttr_) : StrAttr(StrAttr_) { Type = EType::Derived; } ~Derived() override { std::cout << "Derived destructor called." << std::endl; } void Print() const override { std::cout << StrAttr << std::endl; } private: std::string StrAttr; }; int main(int argc, char* argv[]) { std::vector<std::unique_ptr<Base>> Container; Container.emplace_back(std::make_unique<Base>(5)); Container.emplace_back(std::make_unique<Derived>("aggouria")); Container.emplace_back(std::make_unique<Base>(75)); Container.emplace_back(std::make_unique<Derived>("ntomates")); Container.emplace_back(std::make_unique<Base>(18)); Container.emplace_back(std::make_unique<Derived>("karpouzia")); Container.emplace_back(std::make_unique<Base>(420)); Container.emplace_back(std::make_unique<Base>(9)); for (const auto& Class : Container) { if (Class->GetType() == EType::Derived) { static_cast<Derived*>(Class.get())->Print(); } else { Class->Print(); } } system("pause"); return 0; } Θα έχεις στη base class σου ένα enum όπου θα έχει τον τύπο της κλάσης σου. Στη συνέχεια όταν θες να δεις τον τύπο ενός object, σου αρκεί να συγκρίνεις το type που έχεις αποθηκεύσει. Αν λοιπόν ο τύπος του object που έχεις είναι Derived, κάνεις ένα static_cast για να πάρεις το derived type και καλείς όποια συνάρτηση της derived κλάσης θέλεις. Αν σε μπερδεύουν τα unique_ptr και στην τάξη έχετε κάνει μόνο "κανονικούς" pointers και new/delete κλπ, βάλε αυτά που έχετε μάθει (αν και "λάθος", δεν έχει τόση σημασία ακόμα, ειδικά αν δεν πολυνοιάζει και τον καθηγητή). Το εχω κάνει αυτο ο Vector crasharei ακομα... 1) κανε κοπιπειστνσε code tag. 2) https://www.visualstudio.com/vs/community/ Δεν το πολυ κατάλαβα.. :/
Moderators Kercyn Δημοσ. 18 Ιουνίου 2017 Moderators Δημοσ. 18 Ιουνίου 2017 Βαλε τοτε τον κωδικα σου, πού κρασαρει και τι σου λεει. 1
defacer Δημοσ. 18 Ιουνίου 2017 Δημοσ. 18 Ιουνίου 2017 Πρώτον, ποτέ πολυμορφικά αντικείμενα σε κάποιο container by value. Δε λειτουργεί έτσι η γλώσσα, αν το κάνεις αυτό έχεις το λεγόμενο slicing. Πρέπει να λειτουργείς μέσω pointers όπως σου είπαν. Δεύτερον, αν λειτουργείς με pointers πρέπει να προσέχεις τι κάνεις γιατί αλλιώς crash. Αυτό είναι που σου συμβαίνει τώρα. Γιατί ακριβώς, χωρίς τον κώδικα δεν έχουμε ιδέα. 1
solarpower Δημοσ. 18 Ιουνίου 2017 Δημοσ. 18 Ιουνίου 2017 Δες μήπως shared_ptrs βοηθούν. https://stackoverflow.com/questions/15731670/stdvector-of-objects-pointers-smart-pointers-to-pass-objects-buss-error 1
Solidios Δημοσ. 18 Ιουνίου 2017 Μέλος Δημοσ. 18 Ιουνίου 2017 Βαλε τοτε τον κωδικα σου, πού κρασαρει και τι σου λεει. Ειναι runtime error, compile κάνει.
solarpower Δημοσ. 18 Ιουνίου 2017 Δημοσ. 18 Ιουνίου 2017 Επίσης μπορείς να δεις τι αντικείμενο έχεις από το δείκτη: https://en.wikipedia.org/wiki/Run-time_type_information
Moderators Kercyn Δημοσ. 18 Ιουνίου 2017 Moderators Δημοσ. 18 Ιουνίου 2017 Ε ναι βρε τζουτζουκο, βαλε τον καταραμενο τον κωδικα να δουμε κι εμεις το γινεται. Ή κανε step over να δεις ακριβως σε ποια γραμμη σκαει.
Solidios Δημοσ. 18 Ιουνίου 2017 Μέλος Δημοσ. 18 Ιουνίου 2017 (επεξεργασμένο) Ε ναι βρε τζουτζουκο, βαλε τον καταραμενο τον κωδικα να δουμε κι εμεις το γινεται. Ή κανε step over να δεις ακριβως σε ποια γραμμη σκαει. #include <iostream> #include <string> #include <fstream> #include <vector> #include <algorithm> #include <sstream> #include <iomanip> using namespace std; class MyExc: public exception//êëÜóç exception { public: int ErrCode;//êùäéêüò ëÜèïõò MyExc(int E):ErrCode(E){} }; class buildings//êëÜóç ãéá ôá êôßñéá, êñáôÜåé ôéò ðëçñïöïñßåò ôïõò { protected: string buildingaddress;//ä/óç êôéñßïõ float areaofbuilding;//åìâáäüí óå ô.ì. int yearofownership;//÷ñïíïëïãßá áðü áðïêôÞèçêå áðü ôïí öïñïëïãïýìåíï public: buildings()//constructor { buildingaddress="N/A"; areaofbuilding=0; yearofownership=0; } buildings(string new_buildingaddress, float new_areaofbuilding, int new_yearofownership)//constructor { buildingaddress=new_buildingaddress; areaofbuilding=new_areaofbuilding; yearofownership=new_yearofownership; } buildings(const buildings ©)//constructor { buildingaddress=copy.buildingaddress; areaofbuilding=copy.areaofbuilding; yearofownership=copy.yearofownership; } virtual ~buildings()//destructor {} bool operator==(const buildings* tmp)//overload == { if(buildingaddress==tmp->buildingaddress) return true; else return false; } void setnewaddress(string new_address) { buildingaddress=new_address; } friend ostream& operator << (ostream& stream, const buildings& obj)//õðåñöüñôùóç << { stream<<"address: "<<obj.buildingaddress; stream<<"\nArea of building: "<<obj.areaofbuilding; stream<<"\nYear of ownership: "<<obj.yearofownership; } virtual void print()//virtual óõíÜñôçóç {} virtual float calculate_tax()//virtual óõíÜñôçóç {} virtual void sethomevalues(string buildaddress,int areaofbuild,int yearofowner,int fl, bool flatappart)//virtual óõíÜñôçóç {} virtual void setcomvalues(string buildaddress,int areaofbuild,int yearofowner, int c_road)//virtual óõíÜñôçóç {} virtual void setemptylotvalues(string buildaddress,int areaofbuild,int yearofowner, bool inorout, bool farm)//virtual óõíÜñôçóç {} }; class home: public buildings//êëÜóç ãéá ôá óðßôéá , êëçñïíïìåß áðü ôçí êëÜóç buildings { private: int floor;//üñïöïò bool flatorappart;//áí åßíáé äéáìÝñéóìá ç ôéìÞ åßíáé 1, áí åßíáé ìïíïêáôïéêßá ç ôéìÞ åßíáé 0 public: float calculate_tax()//õðïëãéóìüò ôïõ öüñïõ ãéá ôï óðßôé { float enfia; if(flatorappart==false) { enfia=(1.3*areaofbuilding)+150; return enfia; } else { enfia=(1.1*areaofbuilding)+(5*floor)+100; return enfia; } } void sethomevalues(string new_buildingaddress, int new_areaofbuilding, int new_yearofownership, int new_floor, bool new_flatorappart )//setter ôéìþí ãéá ôï áñ÷åßï { buildingaddress=new_buildingaddress; areaofbuilding=new_areaofbuilding; yearofownership=new_yearofownership; floor=new_floor; flatorappart=new_flatorappart; } friend ostream& operator << (ostream& stream, const home& obj)//õðåñöüñôùóç << { stream<<"Floor: "<<obj.floor; stream<<"\nFlat of appartment: "<<obj.flatorappart; } home()//constructor { floor=0; flatorappart=false; } home(const home& copy): buildings(copy.buildingaddress, copy.areaofbuilding, copy.yearofownership)//constructor { floor=copy.floor; flatorappart=copy.flatorappart; } ~home()//destructor {} void print()//åêôýðùóç óôïé÷åßùí óôçí ïèüíç { cout << "\nData: "<<buildingaddress << '|' << areaofbuilding << '|' << yearofownership << '|' << floor << '|' << flatorappart << '|'; } }; class commercial: public buildings//êëÜóç ãéá åìðïñéêÜ áêßíçôá, êëçñïíïìåß áðü ôçí êëÜóç buildings { private: int com_road;//(1-10) âáèìïëïãßá ãéá ôï ðüóï åìðïñéêüò åßíáé ï äñüìïò óôïí ïðïßï âñßóêåôáé ôï áêßíçôï ð.÷. Åñìïý=10 public: float calculate_tax()//õðïëïãéóìüò ôïõ öüñïõ { float enfia; enfia=(2*areaofbuilding)+(200*com_road); return enfia; } friend ostream& operator << (ostream& stream, const commercial& obj)//õðåñöüñôùóç << { stream<<"Commeriality of the road: "<<obj.com_road; } commercial()//constructor { com_road=0; } commercial(const commercial& copy): buildings(copy.buildingaddress, copy.areaofbuilding, copy.yearofownership)//constructor { com_road=copy.com_road; } ~commercial()//destructor {} void setcomvalues(string new_buildingaddress, int new_areaofbuilding, int new_yearofownership, int new_com_road)//setter ôéìþí ãéá ôï áñ÷åßï { buildingaddress=new_buildingaddress; areaofbuilding=new_areaofbuilding; yearofownership=new_yearofownership; com_road=new_com_road; } void print()//åêôýðùóç óôïé÷åßùí óôçí ïèüíç { cout << "\nData: "<<buildingaddress << '|' << areaofbuilding << '|' << yearofownership << '|' << com_road << '|'; } }; class emptylot: public buildings//êëÜóç ãéá "÷ùñÜöéá", êëçñïíïìåß áðü ôçí êëÜóç buildings { private: bool InOrOut;//Åíôüò=0 Þ åêôüò ïéêéóìïý=1 bool farmable;//Êáëëéåñãåßôáé=0 Þ ü÷é=1 public: float calculate_tax()//õðïëïãéóìüò ôïõ öüñïõ { float enfia; if(InOrOut==0) { enfia=(0.3*areaofbuilding)+250; return enfia; } else { enfia=(0.3*areaofbuilding)+70; return enfia; } } friend ostream& operator << (ostream& stream, const emptylot& obj)//õðåñöüñôùóç << { stream<<"Inside a settlement?"<<obj.InOrOut; stream<<"\nIs it farmable?"<<obj.farmable; } emptylot()//constructor { InOrOut=false; farmable=false; } emptylot(const emptylot& copy): buildings(copy.buildingaddress, copy.areaofbuilding, copy.yearofownership)//constructor { InOrOut=copy.InOrOut; farmable=copy.farmable; } ~emptylot()//destructor {} void setemptylotvalues(string new_buildingaddress, int new_areaofbuilding, int new_yearofownership, bool new_inorout, bool new_farmable)//setter ôéìþí ãéá ôï áñ÷åßï { buildingaddress=new_buildingaddress; areaofbuilding=new_areaofbuilding; yearofownership=new_yearofownership; InOrOut=new_inorout; farmable=new_farmable; } void print()//åêôýðùóç óôïé÷åßùí óôçí ïèüíç { cout << "\nData: "<< buildingaddress << '|' << areaofbuilding << '|' << yearofownership << '|' << InOrOut << '|' << farmable << '|'; } }; class ENFIA_Application//êëÜóç ãéá ôá óôïé÷åßá ôïõ öïñïëïãïýìåíïõ { private: string name_sur;//ïíïìáôåðþíõìï string home_address;//äéåýèõíóç êáôïéêßáò string AFM;//Á.Ö.Ì. int yearofapplication;//¸ôïò ðïõ Ýãéíå ç áßôçóç vector <buildings*> vec;//vector ìå áíôéêåßìåíá ôýðïõ buildings bool markasfalse;//Åßíáé Üêõñç=1, äåí åßíáé Üêõñç=0 ç äÞëùóç public: ENFIA_Application()//constructor { name_sur="N/A"; home_address="N/A"; AFM="N/A"; yearofapplication=0; markasfalse=false; } ENFIA_Application(const ENFIA_Application ©)//constructor { name_sur=copy.name_sur; home_address=copy.home_address; AFM=copy.AFM; yearofapplication=copy.yearofapplication; vec=copy.vec; markasfalse=copy.markasfalse; } ~ENFIA_Application()//destructor {} void setenfiavalues()//setter ôéìþí { cout<<"Give the taxpayers' name:"<<endl; fflush(stdin); getline(cin,name_sur); cout<<"Give his/her home address:"<<endl; fflush(stdin); getline(cin,home_address); cout<<"Give his/her AFM:"<<endl; fflush(stdin); getline(cin,AFM); cout<<"Give the year of the application:"<<endl; fflush(stdin); cin>>yearofapplication; } void setafm(string new_afm) { AFM=new_afm; } void putinvector( buildings* obj)//åéóáãùãÞ óôïé÷åßïõ óôïí vector { vec.push_back(obj); } bool operator==(const ENFIA_Application& tmp)//operator == { if (AFM==tmp.AFM) return true; else return false; } void setinvalidapp()//áëëáãÞ áßôçóçò óå Üêõñç { char an; do{ cout<<"Do you wish to mark this application as invalid?"<<endl; cout<<"(Y/N)"<<endl; cin>>an; if(an=='Y') markasfalse=true; else if(an=='N') markasfalse=false; else cout<<"Please select a valid letter and press return:"<<endl; }while(an!='Y' && an!='N'); } friend ostream& operator << (ostream& stream, ENFIA_Application& obj)//õðåñöüñôùóç << ãéá áíôéêåßìåíá ENFIA_Application { vector <buildings*> ::iterator it; stream<<"\nTaxpayers' name and surname: "<<obj.name_sur; stream<<"\nHome address: "<<obj.home_address; stream<<"\nAFM: "<<obj.AFM; stream<<"\nYear of application: "<<obj.yearofapplication; for(it=obj.vec.begin();it!=obj.vec.end();++it) { //casting ãéá íá âñïýìå ôïí ôýðï ôïõ áíôéêåéìÝíïõ home *h = dynamic_cast <home *> (*it); commercial *c = dynamic_cast <commercial *> (*it); emptylot *e = dynamic_cast <emptylot *> (*it); //üôé äåí åßíáé NULL, åêôõðþíåôáé ôï êáôÜëëçëï print if (h != NULL) { h->print(); } if (c !=NULL) { c->print(); } if (e !=NULL) { e->print(); } } stream<<"\nValid application: "<<obj.markasfalse; } void eraseabuilding()//äéáãñáöÞ êôéñßïõ áðü ôïí vector { buildings b1; int i; string ad; cout<<"Give the address of the building you wish to erase:"<<endl; fflush(stdin); getline(cin,ad); b1.setnewaddress(ad); for(i=0;i<vec.size();i++) if(b1==vec.at(i)) { vec.erase(vec.begin()+i); } } float tax_calc(ENFIA_Application& obj)//õðïëïãéóìüò ôïõ öüñïõ ãéá ôá áêßíçôá ôïõ vector ôçò êÜèå äÞëùóçò { float sum; int i; vector <buildings*> ::iterator it; for(it=obj.vec.begin();it!=obj.vec.end();++it) { //casting ãéá íá âñïýìå ôïí ôýðï ôïõ áíôéêåéìÝíïõ home *h = dynamic_cast <home *> (*it); commercial *c = dynamic_cast <commercial *> (*it); emptylot *e = dynamic_cast <emptylot *> (*it); //üôé äåí åßíáé NULL, êáëåß êáé ôçí áíÜëïãç óõíÜñôçóç calculate_tax if (h != NULL) { sum+=h->calculate_tax(); } if (c !=NULL) { sum+=c->calculate_tax(); } if (e !=NULL) { sum+=e->calculate_tax(); } } return sum; } float calc_forms(ENFIA_Application& obj)//ìåôñÜåé ôá áêßíçôá áíÜ äÞëùóç { int i=0,j; float s; for(j=0;j<obj.vec.size();j++)//äéáôñÝ÷åé ôïí vector i++;//áõîÜíåôáé ôï i êáôÜ 1 ãéá êÜèå áêßíçôï if(i==1) s=tax_calc(obj);//áí ôï i åßíáé 1 (õðÜñ÷åé äçëáäÞ ìüíï Ýíá áêßíçôï óôçí ëßóôá) õðïëïãßæåôáé ï öüñïò ôïõ else return 0;//áëëéþò åðéóôñÝöåôáé ôï 0 } }; int menu(vector <ENFIA_Application> &v); void makeanapplication(vector <ENFIA_Application> &v); void invalidapplication(vector <ENFIA_Application> &v); int modifyanapplicatiopn(vector <ENFIA_Application> &v); void tax_calculation(vector <ENFIA_Application> &v); void tax_calculation_2(vector <ENFIA_Application> &v); void max_tax(vector <ENFIA_Application> &v); int main() { system("chcp 1253"); vector <ENFIA_Application> v;//vector ìå ôéò áéôÞóåéò ôùí öïñïëïãïýìåíùí menu(v);//êáëåßôáé ôï ìåíïý åðéëïãþí return 0; } int menu(vector <ENFIA_Application> &v)//ìåíïý åðéëïãþí { int ans;//êñáôÜåé ôçí ôéìÞ ðïõ äßíåôáé áðü ôïí ÷ñÞóôç ãéá ôï ìåíïý system("cls"); for (int i = 0; i < 80; i++) {cout << "=";}//Ïñéæüíôéá ãñáììÞ áðü 80 ÷áñáêôÞñåò = cout << "" << setw(56) << "Please select a vaild number and press return:" << setw(24) << "";//Óôïß÷éóç óôï êÝíôñï ôçò ïèüíçò for (int i = 0; i < 80; i++) {cout << "=";}//Ïñéæüíôéá ãñáììÞ áðü 80 ÷áñáêôÞñåò = cout<<endl; cout<<"Make a new application------1"<<endl; cout<<"Change an application-------2"<<endl; cout<<"Mark an invalid application-3"<<endl; cout<<"View data-------------------4"<<endl; cout<<"Exit------------------------5"<<endl; for (int i = 0; i < 80; i++) {cout << "=";}//Ïñéæüíôéá ãñáììÞ áðü 80 ÷áñáêôÞñåò = cout<<endl; cin>>ans; switch(ans) { case 1: try{//ãéá ôï äéÜâáóìá áðü áñ÷åßï makeanapplication(v); } catch(MyExc e)//exception handler { if (e.ErrCode==1) { cout<<"cannot open file"<<endl; return 1; } } menu(v); break; case 2: modifyanapplicatiopn(v); menu(v); break; case 3: invalidapplication(v); menu(v); break; case 4: cout<<"Show applications with total tax more than X euros-----------------1"<<endl; cout<<"Show applications with tax for a single building more than X euros-2"<<endl; cout<<"Show 10 applications with the biggest tax--------------------------3"<<endl; cin>>ans; switch(ans) { case 1: tax_calculation(v); menu(v); break; case 2: tax_calculation_2(v); menu(v); break; case 3: max_tax(v); menu(v); break; default: cout<<"You didn't select a valid number, please try again!"<<endl; menu(v); } case 5: cout<<"Extited! Have a nice day!"<<endl; return 0; default: cout<<"You didn't select a valid number, please try again!"<<endl; menu(v); } } void makeanapplication(vector <ENFIA_Application> &v)//äçìéïõñãßá íÝáò äÞëùóçò { //-------------------ÄÞëùóç ìåôáâëçôþí----------------// ENFIA_Application enfapp;//áíôéêåßìåíï ôýðïõ ENFIA_Application char answ,type,answer,type1,ans;//ó÷åäüí üëá äÝ÷ïíôáé áðáíôÞóåéò áðü ôïí ÷ñÞóôç //Ôá ðáñáêÜôù ÷ñçóéìïðïéïýíôáé óôï "ðÝñáóìá" ôéìþí óôïí åéäéêü setter string buildaddress; int areaofbuild,yearofowner,fl,c_road; bool flatappart,inorout,farm; home h; //-----------------ÔÝëïò äÞëùóçò ìåôáâëçôþí---------// do{ cout<<"Do you want to read from a file?"<<endl; cout<<"(Y/N)"<<endl; cin>>answ; if(answ=='Y')//äéÜâáóìá áðü áñ÷åßï { enfapp.setenfiavalues();//äßíïíôáé ïé ôéìÝò ôïõ öïñïëïãïýìåíïõ ðñþôá ifstream file("test.txt"); do{ if(file.is_open())//åëÝã÷åôáé áí Üíïéîå ôï áñ÷åßï { fflush(stdin); file>>type1,'|';//äéáâÜæåôáé ï ðñþôïò ÷áñáêôÞñáò } else throw MyExc(1);//áí äåí áíïßîåé, ãßíåôáé throw if(type1=='K')//áí ï ôýðïò ðïõ äéáâáóôåß åßíáé êáôïéêßá { buildings *b=new home; //îåêéíÜåé ôï äéÜâáóìá áðü ôï áñ÷åßï êáé ìåôÜ äßíïíôáé ïé ôéìÝò óôïí åéäéêü setter file.seekg(1,ios::cur); getline(file,buildaddress,'|'); file>>areaofbuild, '|'; file.seekg(1,ios::cur); file>>yearofowner, '|'; file.seekg(1,ios::cur); file>>fl, '|'; file.seekg(1,ios::cur); file>>flatappart, '|'; b->sethomevalues(buildaddress,areaofbuild,yearofowner,fl,flatappart); enfapp.putinvector( ; file.seekg(1,ios::cur); } if(type1=='Å')//áí ï ôýðïò ðïõ äéáâáóôåß åßíáé åìðïñéêü áêßíçôï { buildings *b=new commercial; //îåêéíÜåé ôï äéÜâáóìá áðü ôï áñ÷åßï êáé ìåôÜ äßíïíôáé ïé ôéìÝò óôïí åéäéêü setter file.seekg(1,ios::cur); getline(file,buildaddress,'|'); file>>areaofbuild, '|'; file.seekg(1,ios::cur); file>>yearofowner, '|'; file.seekg(1,ios::cur); file>>c_road, '|'; file.seekg(1,ios::cur); b->setcomvalues(buildaddress,areaofbuild,yearofowner,c_road); enfapp.putinvector( ; } if(type1=='Ï')//áí ï ôýðïò ðïõ äéáâáóôåß åßíáé ïéêüðåäï { buildings *b=new emptylot; //îåêéíÜåé ôï äéÜâáóìá áðü ôï áñ÷åßï êáé ìåôÜ äßíïíôáé ïé ôéìÝò óôïí åéäéêü setter file.seekg(1,ios::cur); getline(file,buildaddress,'|'); file>>areaofbuild, '|'; file.seekg(1,ios::cur); file>>yearofowner, '|'; file.seekg(1,ios::cur); file>>inorout, '|'; file.seekg(1,ios::cur); file>>farm, '|'; b->setemptylotvalues(buildaddress,areaofbuild,yearofowner,inorout,farm); enfapp.putinvector( ; file.seekg(1,ios::cur); } cout<<"Do you wish to read more?"<<endl; cin>>ans; }while(ans=='Y');//óõíå÷ßæåôáé Þ ü÷é ç áíÜãíùóç áðü ôï áñ÷åßï v.push_back(enfapp); } else if (answ=='N')//áí ï ÷ñÞóôçò äåí èÝëåé íá äéáâÜóåé áðü áñ÷åßï { do{ enfapp.setenfiavalues();//äßíïíôáé ôá óôïé÷åßá ôïõ öïñïëïãïýìåíïõ do{ do{ //åðéëïãÞ áêéíÞôïõ ðñïò öïñïëüãçóç cout<<"Please enter a letter and press return:"<<endl; cout<<"For a house, press K"<<endl; cout<<"For a commercial building, press E"<<endl; cout<<"For an empty lot, press O"<<endl; cin>>type; if(type=='K') { buildings *b=new home; cout<<"Please enter the address of the building:"<<endl; fflush(stdin); getline(cin,buildaddress); cout<<"Now enter the area of the building:"<<endl; fflush(stdin); cin>>areaofbuild; cout<<"The year of ownership:"<<endl; fflush(stdin); cin>>yearofowner; cout<<"Floor number:"<<endl; fflush(stdin); cin>>fl; cout<<"And type 1 if it is an appartment or 0 if it is a flat:"<<endl; fflush(stdin); cin>>flatappart; b->sethomevalues(buildaddress,areaofbuild,yearofowner,fl,flatappart);//êáëåßôáé ï setter enfapp.putinvector( ;//êáëåßôáé ç óõíÜñôçóç ãéá ôçí åê÷þñçóç óôïí vector } else if(type=='E') { buildings *b=new commercial; cout<<"Please enter the address of the building:"<<endl; fflush(stdin); getline(cin,buildaddress); cout<<"Now enter the area of the building:"<<endl; fflush(stdin); cin>>areaofbuild; cout<<"The year of ownership:"<<endl; fflush(stdin); cin>>yearofowner; cout<<"And rate from 1-10 (1=very low, 10=very high) the commerciality of the road:"<<endl; fflush(stdin); cin>>c_road; b->setcomvalues(buildaddress,areaofbuild,yearofowner,c_road);//êáëåßôáé ï setter enfapp.putinvector( ;//êáëåßôáé ç óõíÜñôçóç ãéá ôçí åê÷þñçóç óôïí vector } else if(type=='O') { buildings *b=new emptylot; cout<<"Please enter the address of the building:"<<endl; fflush(stdin); getline(cin,buildaddress); cout<<"Now enter the area of the building:"<<endl; fflush(stdin); cin>>areaofbuild; cout<<"The year of ownership:"<<endl; fflush(stdin); cin>>yearofowner; cout<<"Type 0 if it is inside the settlement or 1 if it is not:"<<endl; fflush(stdin); cin>>inorout; cout<<"And type 0 if it is farmable or 1 if it is not farmable:"<<endl; fflush(stdin); cin>>farm; b->setemptylotvalues(buildaddress,areaofbuild,yearofowner,inorout,farm);//êáëåßôáé ï setter enfapp.putinvector( ;//êáëåßôáé ç óõíÜñôçóç ãéá ôçí åê÷þñçóç óôïí vector } else cout<<"Invalid letter! please try again!"<<endl; }while(type!='K' && type!='E' && type!='O');//áí äùèåß ëÜèïò áðÜíôçóç, ãßíåôáé îáíÜ ðñïóðÜèåéá cout<<"Do you want to add another building?"<<endl; cout<<"(Y/N)"<<endl; cin>>answer; }while(answer=='Y');//ç äéáäéêáóßá óõíå÷ßæåôáé ãéá üëá ôá êôßñéá v.push_back(enfapp);//åéóáãùãÞ ôçò äÞëùóçò óôïí vector cout<<"Do you want to add another application;"<<endl; cout<<"(Y/N)"<<endl; cin>>answer; }while(answer=='Y');//ç äéáäéêáóßá óõíå÷ßæåôáé ãéá üëïõò ôïõò öïñïëïãïýìåíïõò } else cout<<"Invalid letter! Please try again!"<<endl; }while(answ!='Y' && answ!='N');//áí äùèåß ëÜèïò áðÜíôçóç, ãßíåôáé îáíÜ ðñïóðÜèåéá } int modifyanapplicatiopn(vector <ENFIA_Application> &v)//ôñïðïðïßçóç õðÜñ÷ïõóáò äÞëùóçò { //-------------------ÄÞëùóç ìåôáâëçôþí----------------// char an,a,type,ans,an1;//ó÷åäüí üëá äÝ÷ïíôáé áðáíôÞóåéò áðü ôïí ÷ñÞóôç ENFIA_Application e1;//áíôéêåßìåíï ôýðïõ ENFIA_Application string getafm;//Á.Ö.Ì ãéá óõãêñßóåéò //Ôá ðáñáêÜôù ÷ñçóéìïðïéïýíôáé óôï "ðÝñáóìá" ôéìþí óôïí åéäéêü setter string buildaddress; int areaofbuild,yearofowner,fl,c_road; bool flatappart,inorout,farm; //-----------------ÔÝëïò äÞëùóçò ìåôáâëçôþí---------// do{ cout<<"Please enter the AFM of the taxpayer you wish to change:"<<endl; fflush(stdin); getline(cin,getafm);//åéóÜãåôáé ï ÁÖÌ e1.setafm(getafm); vector <ENFIA_Application>::iterator il; for (il=v.begin();il!=v.end();++il)//äéáôñÝ÷åôáé ï vector if(e1==*il)//áí âñåèåß, åêôõðþíïíôáé ôá óôïé÷åßá ôïõ { e1=*il; cout<<*il<<endl; do{ cout<<"Do you want to erase this application?"<<endl; cout<<"(Y/N)"<<endl; cin>>an; if(an=='Y') { v.erase(il);//äéáãñáöÞ áßôçóçò (ãéáôß êñáóÜñåé?) } else if (an=='N') { cout<<"Do you want to erase a building?"<<endl; cout<<"(Y/N)"<<endl; cin>>an; if(an=='Y') { v.erase(il); e1.eraseabuilding();//äéáãñáöÞ áêéíÞôïõ } cout<<"Do you want to make other changes?"<<endl; cout<<"(Y/N)"<<endl; cin>>an1; if(an1=='Y') { v.erase(il); cout<<"Please enter the new values:"<<endl; e1.setenfiavalues();//äßíïíôáé ïé ôéìÝò ôïõ öïñïëïãïýìåíïõ do{ cout<<"Do you want to add a building?"<<endl; cout<<"(Y/N)"<<endl; cin>>an; if (an=='Y')//ðñïóôßèåôáé íÝï áêßíçôï { do{ do{ cout<<"Please enter a letter and press return:"<<endl; cout<<"For a house, press K"<<endl; cout<<"For a commercial building, press E"<<endl; cout<<"For an empty lot, press O"<<endl; cin>>type; if(type=='K') { buildings *b=new home; cout<<"Please enter the address of the building:"<<endl; fflush(stdin); getline(cin,buildaddress); cout<<"Now enter the area of the building:"<<endl; fflush(stdin); cin>>areaofbuild; cout<<"The year of ownership:"<<endl; fflush(stdin); cin>>yearofowner; cout<<"Floor number:"<<endl; fflush(stdin); cin>>fl; cout<<"And type 1 if it is an appartment or 0 if it is a flat:"<<endl; fflush(stdin); cin>>flatappart; b->sethomevalues(buildaddress,areaofbuild,yearofowner,fl,flatappart);//êáëåßôáé ï setter e1.putinvector( ; } else if(type=='E') { buildings *b=new commercial; cout<<"Please enter the address of the building:"<<endl; fflush(stdin); getline(cin,buildaddress); cout<<"Now enter the area of the building:"<<endl; fflush(stdin); cin>>areaofbuild; cout<<"The year of ownership:"<<endl; fflush(stdin); cin>>yearofowner; cout<<"And rate from 1-10 (1=very low, 10=very high) the commerciality of the road:"<<endl; fflush(stdin); cin>>c_road; b->setcomvalues(buildaddress,areaofbuild,yearofowner,c_road); e1.putinvector( ; } else if(type=='O') { buildings *b=new emptylot; cout<<"Please enter the address of the building:"<<endl; fflush(stdin); getline(cin,buildaddress); cout<<"Now enter the area of the building:"<<endl; fflush(stdin); cin>>areaofbuild; cout<<"The year of ownership:"<<endl; fflush(stdin); cin>>yearofowner; cout<<"Type 0 if it is inside the settlement or 1 if it is not:"<<endl; fflush(stdin); cin>>inorout; cout<<"And type 0 if it is farmable or 1 if it is not farmable:"<<endl; fflush(stdin); cin>>farm; b->setemptylotvalues(buildaddress,areaofbuild,yearofowner,inorout,farm); e1.putinvector( ; } else cout<<"Invalid letter! please try again!"<<endl; }while(type!='K' && type!='E' && type!='O'); cout<<"Do you want to add another building?"<<endl; cout<<"(Y/N)"<<endl; cin>>ans; }while(ans!='N'); v.push_back(e1);//åê÷ùñåßôáé óôçí ëßóôá ç "íÝá" äÞëùóç } else if(an!='Y' && an!='N') cout<<"Wrong letter! Please try again!"<<endl; else v.push_back(e1);//åê÷ùñåßôáé óôçí ëßóôá ç "íÝá" äÞëùóç }while(an!='Y' && an!='N'); } else return 1; } else cout<<"Wrong letter! Please try again!"<<endl; }while(an!='Y' && an!='N'); } cout<<"Do you wish to change another application?"<<endl; cout<<"(Y/N)"<<endl; cin>>a; }while(a!='N'); } void invalidapplication(vector <ENFIA_Application> &v)//áëëáãÞ áßôçóçò óå Üêõñç { //-------------------ÄÞëùóç ìåôáâëçôþí----------------// char a;//÷áñáêôÞñáò ãéá óõíÝ÷åéá Þ ü÷é ôçò äéáäéêáóßáò ENFIA_Application a1;//áíôéêåßìåíï ôýðïõ ENFIA_Application string newAFM;//äÝ÷åôáé ôï ÁÖÌ ðïõ åéóÜãåé ï ÷ñÞóôçò ãéá áíáæÞôçóç vector <ENFIA_Application>::iterator il;//iterator ãéá ôïí vector int f=0;//äéáêüðôçò //-----------------ÔÝëïò äÞëùóçò ìåôáâëçôþí---------// do{ cout<<"Please enter the AFM of the taxpayer:"<<endl; cin>>newAFM; a1.setafm(newAFM); for (il=v.begin();il!=v.end();++il) if(a1==*il && f==0) { a1=*il; cout<<*il<<endl;//ôõðþíïíôáé ôá óôïé÷åßá ôïõ v.erase(il);//óâÞíåôáé áðü ôïí vector a1.setinvalidapp();//êáëåßôáé ç óõíÜñôçóç ãéá áëëáãÞ óå Üêõñç áßôçóç v.push_back(a1);//åê÷ùñåßôáé îáíÜ ìå ôçí áëëáãÞ f=1; } f=0; cout<<"Do you wish to change another application?"<<endl; cout<<"(Y/N)"<<endl; cin>>a; }while(a!='N'); } void tax_calculation(vector <ENFIA_Application> &v)//õðïëïãéóìüò öüñïõ êáé åìöÜíéóç áñéèìïý áéôÞóåùí ìåãáëýôåñùí áðü × åõñþ { //-------------------ÄÞëùóç ìåôáâëçôþí----------------// float s,x;//s=óõíïëéêü ðïóü ôïõ öüñïõ, x=× åõñþ int total=0;//óýíïëï äçëþóåùí ðÜíù áðü × åõñþ ENFIA_Application a1;//áíôéåêßìåíï ôýðïõ ENFIA_Application vector <ENFIA_Application>::iterator il;//iterator ãéá ôïí vector //-----------------ÔÝëïò äÞëùóçò ìåôáâëçôþí---------// cout<<"Please enter X in order to display the number of applications with total tax more than X euros:"<<endl; cin>>x;//åéóÜãåôáé ôï × ðïóü for (il=v.begin();il!=v.end();++il)//äéáôñÝ÷åôáé ï vector ìå ôéò áéôÞóåéò { a1=*il; s=a1.tax_calc(a1);//õðïëïãßæåôáé ãéá êÜèå áíôéêåßìåíï ï öüñïò if(s>x) total=total+1;//áí åßíáé ìåãáëýôåñï ôïõ ×, ðñïóôßèåôáé 1 óôï óýíïëï ôùí äçëþóåùí } cout<<"The number is: "<<total<<endl;//åêôýðùóç ôïõ áñéèìïý system("pause"); } void tax_calculation_2(vector <ENFIA_Application> &v)//õðïëïãéóìüò ôïõ öüñïõ ãéá äçëþóåéò ðïõ Ý÷ïõí ìåìïíùìÝíï áêßíçôï ìå öüñï ðÜíù áðü × åõñþ { //-------------------ÄÞëùóç ìåôáâëçôþí----------------// float s=0,x;//s=óõíïëéêü ðïóü ôïõ öüñïõ, x=× åõñþ int total=0;//óýíïëï äçëþóåùí ðÜíù áðü × åõñþ ENFIA_Application a1;//áíôéåêßìåíï ôýðïõ ENFIA_Application vector <ENFIA_Application>::iterator il;//iterator ãéá ôïí vector //-----------------ÔÝëïò äÞëùóçò ìåôáâëçôþí---------// cout<<"Please enter X (in euros)"<<endl; cin>>x;//åéóÜãåôáé ôï × ðïóü for (il=v.begin();il!=v.end();++il)//äéáôñÝ÷åôáé ï vector ìå ôéò áéôÞóåéò { a1=*il; s=a1.calc_forms(a1);//ìåôñéïýíôáé ôá áêßíçôá ôçò êÜèå äÞëùóçò if(s>x) total=total+1;//áí åßíáé ìåãáëýôåñï ôïõ ×, ðñïóôßèåôáé 1 óôï óýíïëï ôùí äçëþóåùí } if(total==0)//áí äåí âñåèïýí äçëþóåéò cout<<"There are no forms with only one building!"<<endl; else//áí âñåèïýí äçëþóåéò cout<<"The number is: "<<total<<endl; system("pause"); } void max_tax(vector <ENFIA_Application> &v)//ïé 10 äçëþóåéò ìå ôïí ìåãáëýôåñï öüñï { //-------------------ÄÞëùóç ìåôáâëçôþí----------------// float s=0;//s=óõíïëéêü ðïóü ôïõ öüñïõ int i,j,f=0;//ìåôñçôÝò êáé "äéáêüðôçò" ENFIA_Application a1,tax[10];//áíôéåêßìåíï ôýðïõ ENFIA_Application vector <ENFIA_Application>::iterator il;//iterator ãéá ôïí vector //-----------------ÔÝëïò äÞëùóçò ìåôáâëçôþí---------// for (il=v.begin();il!=v.end();++il)//äéáôñÝ÷åôáé ï vector ìå ôéò áéôÞóåéò { s=0; a1=*il; s+=a1.tax_calc(a1);//õðïëïãßæåôáé ãéá êÜèå áíôéêåßìåíï ï öüñïò for(i=0;i<9;i++) { if(s>tax[i].tax_calc(tax[i]) && f==0)//áí ï öüñïò ôçò äëÞùóçò ðïõ õðïëïãßóôçêå åßíáé ìåãáëýôåñïò áðü Ýíáí ðïõ õðÜñ÷åé óôïí ðßíáêá { for (j=9-i;j>0;j--) { tax[j]=tax[j-1];//ïëßóèçóç ðñïò ôá äåîéÜ ôùí óôïé÷åßùí ðïõ ðñÝðåé } tax[i]=a1;//åê÷þñçóç ôïõ íÝïõ óôïé÷åßïõ óôïí ðßíáêá //ï "äéáêüðôçò" óôáìáôÜåé ôçí äéáäéêáóßá ìÝóá óôçí if óå ðåñßðôùóç ðïõ ãßíïõí áëëáãÝò óôïí ðßíáêá f=1;//áëëáãÞ ôïõ "äéáêüðôç" } } f=0;//ï "äéáêüðôçò" ìçäåíßæåôáé þóôå íá ãßíïõí óõãêñßóåéò ãéá ôá íÝá óôïé÷åßá } cout<<"The forms with the highest tax are:"<<endl; for (i=0;i<9;i++) { cout<<tax[i];//åêôýðùóç ôùí äçëþóåùí } system("pause"); } Ε ναι βρε τζουτζουκο, βαλε τον καταραμενο τον κωδικα να δουμε κι εμεις το γινεται. Ή κανε step over να δεις ακριβως σε ποια γραμμη σκαει. Και εδώ σκάει : cout<<"Do you want to erase this application?"<<endl; cout<<"(Y/N)"<<endl; cin>>an; if(an=='Y') { v.erase(il);//äéáãñáöÞ áßôçóçò (ãéáôß êñáóÜñåé?) } επίσης ξέρω τι αντικείμενο εχω γιατι μπορω να κανω dynamic_cast στο κώδικα. Πρώτον, ποτέ πολυμορφικά αντικείμενα σε κάποιο container by value. Δε λειτουργεί έτσι η γλώσσα, αν το κάνεις αυτό έχεις το λεγόμενο slicing. Πρέπει να λειτουργείς μέσω pointers όπως σου είπαν. Δεύτερον, αν λειτουργείς με pointers πρέπει να προσέχεις τι κάνεις γιατί αλλιώς crash. Αυτό είναι που σου συμβαίνει τώρα. Γιατί ακριβώς, χωρίς τον κώδικα δεν έχουμε ιδέα. Smart pointers δεν ξέρουμε ακόμα πως λειτουργούν.. Επίσης μπορείς να δεις τι αντικείμενο έχεις από το δείκτη: https://en.wikipedia.org/wiki/Run-time_type_information Δεν καταλαβαίνω την τύφλα μου εκει μέσα.. Επεξ/σία 18 Ιουνίου 2017 από Solidios
παπι Δημοσ. 18 Ιουνίου 2017 Δημοσ. 18 Ιουνίου 2017 Smart pointer κανει το delete για σενα. Καντο απλα με ποιντερς.
Solidios Δημοσ. 18 Ιουνίου 2017 Μέλος Δημοσ. 18 Ιουνίου 2017 Smart pointer κανει το delete για σενα. Καντο απλα με ποιντερς. Pointers χρησιμοποιώ.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα