PC_MAGAS Δημοσ. 22 Οκτωβρίου 2017 Δημοσ. 22 Οκτωβρίου 2017 Καλησπέρα γοργόνες και μάγκες (κατα το ύμισι ή πλήρως), ΄Οπως κοιτούσα και έπαιζα λίγο με C++ έκανα το απλό χαζό προγραμματάκι που απλά κάνει "validate" Json αρχεία (και καλά απλά να δω πως πάει το inheritance) #include <iostream> #include <fstream> class FileValidator{ public: FileValidator(char *fileName); ~FileValidator(); bool validate(); char* getFileName(); private: const char* filename; protected: std::ifstream openFile(); void closeFile(std::ifstream file); }; class JsonValidator:public FileValidator{ public: bool validate(); }; int main() { JsonValidator v((char*)"./dummy.txt"); if(v.validate()){ std::cout<<"The file "<<v.getFileName()<<" is a valid JSON (Yeah,right)"; } else { std::cout<<"WTF you gave me bro!!!"; } return 1; } FileValidator::FileValidator(char *fileName){ this->filename=fileName; } FileValidator::~FileValidator(){ } bool FileValidator::validate(){ return false; } char* FileValidator::getFileName(){ return (char *)this->filename; } std::ifstream FileValidator::openFile(){ std::ifstream file(this->filename); return file; } void FileValidator::closeFile(std::ifstream file){ file.close(); } bool JsonValidator::validate(){ bool valid=false; std::ifstream file = this->openFile(); std::string s; //Dummy logic just for inheritance demontstration while (std::getline(file, s)) { if(s.find('{')!=std::string::npos){ valid=true; break; } } this->closeFile(file); return valid; } Ουσιαστικά στον παραπάνω οχετό έχω την FileValidator και η JsonValidator κάνει inherit αυτήν. Αλλά ο compiler μου φτύνει το κάτοθι error: ./inheritance.cpp: In function ‘int main()’: ./inheritance.cpp:25:39: error: no matching function for call to ‘JsonValidator::JsonValidator(char*)’ JsonValidator v((char*)"./dummy.txt"); ^ ./inheritance.cpp:19:7: note: candidate: JsonValidator::JsonValidator() class JsonValidator:public FileValidator{ ^ ./inheritance.cpp:19:7: note: candidate expects 0 arguments, 1 provided ./inheritance.cpp:19:7: note: candidate: JsonValidator::JsonValidator(const JsonValidator&) ./inheritance.cpp:19:7: note: no known conversion for argument 1 from ‘char*’ to ‘const JsonValidator&’ In file included from /usr/include/c++/5/ios:42:0, from /usr/include/c++/5/ostream:38, from /usr/include/c++/5/iostream:39, from ./inheritance.cpp:1: /usr/include/c++/5/bits/ios_base.h: In copy constructor ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’: /usr/include/c++/5/bits/ios_base.h:855:5: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private ios_base(const ios_base&); ^ In file included from /usr/include/c++/5/ios:44:0, from /usr/include/c++/5/ostream:38, from /usr/include/c++/5/iostream:39, from ./inheritance.cpp:1: /usr/include/c++/5/bits/basic_ios.h:67:11: error: within this context class basic_ios : public ios_base ^ In file included from ./inheritance.cpp:2:0: /usr/include/c++/5/fstream: In copy constructor ‘std::basic_ifstream<char>::basic_ifstream(const std::basic_ifstream<char>&)’: /usr/include/c++/5/fstream:455:11: note: synthesized method ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’ first required here class basic_ifstream : public basic_istream<_CharT, _Traits> ^ In file included from /usr/include/c++/5/ios:43:0, from /usr/include/c++/5/ostream:38, from /usr/include/c++/5/iostream:39, from ./inheritance.cpp:1: /usr/include/c++/5/streambuf: In copy constructor ‘std::basic_filebuf<char>::basic_filebuf(const std::basic_filebuf<char>&)’: /usr/include/c++/5/streambuf:804:7: error: ‘std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]’ is private basic_streambuf(const basic_streambuf&); ^ In file included from ./inheritance.cpp:2:0: /usr/include/c++/5/fstream:72:11: error: within this context class basic_filebuf : public basic_streambuf<_CharT, _Traits> ^ /usr/include/c++/5/fstream: In copy constructor ‘std::basic_ifstream<char>::basic_ifstream(const std::basic_ifstream<char>&)’: /usr/include/c++/5/fstream:455:11: note: synthesized method ‘std::basic_filebuf<char>::basic_filebuf(const std::basic_filebuf<char>&)’ first required here class basic_ifstream : public basic_istream<_CharT, _Traits> ^ ./inheritance.cpp: In member function ‘std::ifstream FileValidator::openFile()’: ./inheritance.cpp:54:10: note: synthesized method ‘std::basic_ifstream<char>::basic_ifstream(const std::basic_ifstream<char>&)’ first required here return file; Έτσι απο ότι κατάλαβα θα πρέπει να κάνω redeclare Constructor και Destructor αλλά δεν μπορώ να καταλάγω το γιατί, δεν θα πρέπει να τους πάρει από πάνω (από την παπα-Κλάση);
Moderators Kercyn Δημοσ. 22 Οκτωβρίου 2017 Moderators Δημοσ. 22 Οκτωβρίου 2017 Με μια γρήγορη ματιά που έριξα, το validate στο FileValidator πρέπει να είναι virtual και στο JsonValidator πρέπει να το κάνεις override. Στο JsonValidator δεν υπάρχει constructor που να δέχεται char* ως argument. Επίσης τα αρχεία δε χρειάζεται να τα κλείνεις εσύ και τα C-style casts που έχεις είναι πρακτικά η χειρότερη επιλογή που θα μπορούσες να κάνεις (ένα παράδειγμα). Έτσι απο ότι κατάλαβα θα πρέπει να κάνω redeclare Constructor και Destructor αλλά δεν μπορώ να καταλάγω το γιατί, δεν θα πρέπει να τους πάρει από πάνω (από την παπα-Κλάση); Όχι, δε φτιάχνεις FileValidator, φτιάχνεις JsonValidator. Δεν είναι το ίδιο πράγμα.
PC_MAGAS Δημοσ. 22 Οκτωβρίου 2017 Μέλος Δημοσ. 22 Οκτωβρίου 2017 Με μια γρήγορη ματιά που έριξα, το validate στο FileValidator πρέπει να είναι virtual και στο JsonValidator πρέπει να το κάνεις override. Στο JsonValidator δεν υπάρχει constructor που να δέχεται char* ως argument. Επίσης τα αρχεία δε χρειάζεται να τα κλείνεις εσύ και τα C-style casts που έχεις είναι πρακτικά η χειρότερη επιλογή που θα μπορούσες να κάνεις (ένα παράδειγμα). Όχι, δε φτιάχνεις FileValidator, φτιάχνεις JsonValidator. Δεν είναι το ίδιο πράγμα. Σε απλά Ελληνικά θέλω καλύτερο Study material αυτό που έχω δεν το καλύπτει.
kaliakman Δημοσ. 22 Οκτωβρίου 2017 Δημοσ. 22 Οκτωβρίου 2017 Σε απλά Ελληνικά θέλω καλύτερο Study material αυτό που έχω δεν το καλύπτει. Πρέπει να δεις λίγο καλύτερα πως δουλεύει το inheritance στην c++ και γενικά οι κλασσεις. Ένα καλό βιβλίο είναι το accelerated c++ αν και λίγο δύσκολο γιατί όπως λέει και το όνομα πάει γρήγορα.
defacer Δημοσ. 22 Οκτωβρίου 2017 Δημοσ. 22 Οκτωβρίου 2017 Έτσι απο ότι κατάλαβα θα πρέπει να κάνω redeclare Constructor και Destructor αλλά δεν μπορώ να καταλάγω το γιατί, δεν θα πρέπει να τους πάρει από πάνω (από την παπα-Κλάση); Προσπερνάω όλα τα άλλα κακώς κείμενα (αργκκκκ το παράδειγμα inheritance είναι τόσο άπειρα πολύ κακό!) για να απαντήσω κατευθείαν σ' αυτό που λες. Όχι, στη C++ (και όχι μόνο) δε θα πρέπει να τους πάρει από πάνω. Ενδεχομένως να περίμενες ότι θα συμπεριφερόταν το ίδιο με άλλες γλώσσες (PHP?) αλλά ο κοντός ψαλμός αλληλούια είναι πως αυτό θα δημιουργούσε περισσότερα προβλήματα απ' ότι θα έλυνε. Ίσως θα έπρεπε να αντιστρέψεις την ερώτηση: γιατί να πρέπει να τους πάρει από πάνω; Τι κερδίζεις; Anyway, αν όντως θες constructor που παίρνει char* τότε JsonValidator(char* fileName) : FileValidator(fileName) {} είτε το πιο μονδέρνο (αν και δε θα το έκανα ο ίδιος) class JsonValidator : public FileValidator { using FileValidator::FileValidator; }
PC_MAGAS Δημοσ. 22 Οκτωβρίου 2017 Μέλος Δημοσ. 22 Οκτωβρίου 2017 Προσπερνάω όλα τα άλλα κακώς κείμενα (αργκκκκ το παράδειγμα inheritance είναι τόσο άπειρα πολύ κακό!) για να απαντήσω κατευθείαν σ' αυτό που λες. Όχι, στη C++ (και όχι μόνο) δε θα πρέπει να τους πάρει από πάνω. Ενδεχομένως να περίμενες ότι θα συμπεριφερόταν το ίδιο με άλλες γλώσσες (PHP?) αλλά ο κοντός ψαλμός αλληλούια είναι πως αυτό θα δημιουργούσε περισσότερα προβλήματα απ' ότι θα έλυνε. Ίσως θα έπρεπε να αντιστρέψεις την ερώτηση: γιατί να πρέπει να τους πάρει από πάνω; Τι κερδίζεις; Anyway, αν όντως θες constructor που παίρνει char* τότε JsonValidator(char* fileName) : FileValidator(fileName) {} είτε το πιο μονδέρνο (αν και δε θα το έκανα ο ίδιος) class JsonValidator : public FileValidator { using FileValidator::FileValidator; } Γι αυτό κάνεις μικρά examples για να δείς συμπεριφορά πρωτού πεις πως είσαι production master Δε γι αυτό δοκιμάζω την "δοκιμάζοντας και βρίζοντας" μέθοδο διδασκαλίας. Δοκιμάζεις πωε θα έχεις ένα Χ αποτέλεσμα σε άλλη γλώσσα. Πρέπει να δεις λίγο καλύτερα πως δουλεύει το inheritance στην c++ και γενικά οι κλασσεις. Ένα καλό βιβλίο είναι το accelerated c++ αν και λίγο δύσκολο γιατί όπως λέει και το όνομα πάει γρήγορα. Κάτι σε αργό έχει το μαγαζί;
παπι Δημοσ. 22 Οκτωβρίου 2017 Δημοσ. 22 Οκτωβρίου 2017 Κακο παράδειγμα. Θες δυο+ διαφορετικά πράματα τα οποία έχουν ένα κοινό. Το κοινό είναι η base class. Ένα απλό παράδειγμα που μου έρχεται, είναι το object. Που θα έχει έναν ref counter ένα equals άντε και ένα tostring. Έτσι μπορείς να φτιάξεις δύο τελείως οτιναναι κλάσεις που θα έχουν κάτι κοινό.
PC_MAGAS Δημοσ. 23 Οκτωβρίου 2017 Μέλος Δημοσ. 23 Οκτωβρίου 2017 Κακο παράδειγμα. Θες δυο+ διαφορετικά πράματα τα οποία έχουν ένα κοινό. Το κοινό είναι η base class. Ένα απλό παράδειγμα που μου έρχεται, είναι το object. Που θα έχει έναν ref counter ένα equals άντε και ένα tostring. Έτσι μπορείς να φτιάξεις δύο τελείως οτιναναι κλάσεις που θα έχουν κάτι κοινό. Αλλά κάνει simulate τι θα δεις η τι έχεις δει προκειμένου να το δεις σε άλλη βάση. Το να έχω μια κλάση με κοινο Constructor είναι ψωμοτύρι στην php.
παπι Δημοσ. 24 Οκτωβρίου 2017 Δημοσ. 24 Οκτωβρίου 2017 (επεξεργασμένο) Δεν βγαζει νοημα, τι ειναι η FileValidator? class, interface ή abstract ? αν θες απλα να δεις πως συμπεριφερεται το inheritance στη c++, θα κατσω να σου γραψω ενα echo #include <iostream> class IInterface { public: virtual ~IInterface() = default; virtual void HelloWorld() = 0; }; class Abstract { public: Abstract() { std::cout << "Abstract::Abstruct()"<<std::endl; } ~Abstract() { std::cout << "Abstract::~Abstract()" << std::endl; } void HelloWorld() { std::cout << "Abstract::HelloWorld()" << std::endl; } virtual void SayMyDerived() = 0; }; class Base { public: Base() { std::cout << "Base::Base()" << std::endl; } Base(int) { std::cout << "Base::Base(int)" << std::endl; } ~Base() { std::cout << "Base::~Base()" << std::endl; } }; class Derived0 : public IInterface { public: ~Derived0() { std::cout << "Derived0::~Derived0()" << std::endl; } void HelloWorld() override { std::cout << "Derived0::HelloWorld()" << std::endl; } }; class Derived1 : public Abstract { public: Derived1() { std::cout << "Derived1::Derived1" << std::endl; } ~Derived1() { std::cout << "Derived1::~Derived1" << std::endl; } void SayMyDerived() override { std::cout << "Derived1::SayMyDrived()" << std::endl; } private: }; class Derived2 : public Base { public: Derived2() { std::cout << "Derived2::Derived2()" << std::endl; } Derived2(int) { Base::Base(1+1); std::cout << "Derived2::Derived2(int)" << std::endl; } ~Derived2() { std::cout << "Drived2::~Derived2()" << std::endl; } }; class Derived3 : public Derived1 { public: Derived3() { std::cout << "Derived3::Derived3()" << std::endl; } ~Derived3() { std::cout << "Derived::~Derived3" << std::endl; } void SayMyDerived() override { std::cout << "Derived3::SayMyDerived" << std::endl; } }; class Derived4 : public Derived3 { public: Derived4() { std::cout << "Derived4::Derived4()" << std::endl; } ~Derived4() { std::cout << "Derived4::~Derived4" << std::endl; } void SayMyDerived() override { std::cout << "Derived4::SayMyDerived" << std::endl; Derived3::SayMyDerived(); } }; int main(int, char**) { IInterface *i = new Derived0(); i->HelloWorld(); delete i; Abstract *a = new Derived1(); a->SayMyDerived(); delete a; delete new Derived2(); delete new Derived2(1); Derived3 * d3 = new Derived3(); d3->SayMyDerived(); delete d3; Derived4 *d4 = new Derived4(); d4->SayMyDerived(); delete d4; return 0; } Εδω ειναι ολες οι πιπες που μπορεις να συναντησεις. Μονο το virtual inheritance λειπει, αλλα αυτο αστο μαζι με το multiple inheritance Επεξ/σία 24 Οκτωβρίου 2017 από παπι
solarpower Δημοσ. 24 Οκτωβρίου 2017 Δημοσ. 24 Οκτωβρίου 2017 Δεν κάνει compile: Μπορείς να το βάλεις εδώ https://www.onlinegdb.com/online_c++_compiler και να δημοσιεύσεις το σύνδεσμο απευθείας στο κώδικά σου!
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα