Καλησπέρα. Σήμερα έγραψα έναν κώδικα ο οποίος πετάει σφάλματα κατά την διάκρεια του compilation και δεν ξέρω γιατί.
Ψάχντοντας βρήκα κάτι σχετικά με circular references αλλά δεν καταλαβαίνω τι σημαίνει. Νομίζω έχει σχέσει με τον τρόπο
που κάνω include τα header files.
Εάν θέλετε μπορείτε να κατεβάσετε το project (visual studio) εδώ για να δείτε τον κώδικα ποιο εύκολα.
Main.cpp
Κώδικας:#include <iostream> #include "trie_node.h" int main(void) { system("pause"); return 0; }
trie_node.h
Κώδικας:#pragma once #include "map.h" class TrieNode { private: Map map; bool end_of_world; public: TrieNode(); Map getMap(); void setBool(bool value); bool getBool(); };
trie_node.cpp
Κώδικας:#include "trie_node.h" TrieNode::TrieNode() { this->end_of_world = false; } Map TrieNode::getMap() { return this->map; } void TrieNode::setBool(bool value) { this->end_of_world = value; } bool TrieNode::getBool() { return this->end_of_world; }
map_node.h
Κώδικας:#pragma once #include "trie_node.h" class MapNode { private: char ch; ::MapNode *next; TrieNode *trie_node; public: MapNode(); char getChar(); ::MapNode *getNext(); TrieNode *getTrie(); void setNext(::MapNode *new_node); void setCh(char ch); void setTrie(TrieNode *new_node); };
map_node.cpp
Κώδικας:#include "map_node.h" MapNode::MapNode() { this->ch = '\0'; this->next = nullptr; this->trie_node = nullptr; } char MapNode::getChar() { return this->ch; } MapNode *MapNode::getNext() { return this->next; } TrieNode *MapNode::getTrie() { return this->trie_node; } void MapNode::setNext(MapNode *new_node) { this->next = new_node; } void MapNode::setCh(char ch) { this->ch = ch; } void MapNode::setTrie(TrieNode *new_node) { this->trie_node = new_node; }
map.h
Κώδικας:#pragma once #include "map_node.h" class Map { private: MapNode *head; MapNode *tail; int size; public: Map(); void insert(char ch, TrieNode *new_node); TrieNode *search(char h); int getSize(); };
map.cpp
Κώδικας:#include "map.h" Map::Map() { this->head = nullptr; this->tail = nullptr; this->size = 0; } void Map::insert(char ch, TrieNode *trie_node) { MapNode *new_node = new MapNode(); new_node->setCh(ch); new_node->setTrie(trie_node); this->size++; if (this->head == nullptr) { this->head = new_node; this->tail = new_node; } else { this->tail->setNext(new_node); this->tail = new_node; } } TrieNode *Map::search(char ch) { MapNode *current = this->head; while (current != nullptr) { if (current->getChar() == ch) return current->getTrie(); current = current->getNext(); } return nullptr; } int Map::getSize() { return this->size; }
Visual Studio Error Codes:
Δείτε τα error codes εδώ
Εμφάνιση 1-13 από 13
Θέμα: C++ Συντακτικά λάθη;
-
08-07-17, 19:37 C++ Συντακτικά λάθη; #1
Τελευταία επεξεργασία από το μέλος babaliaris : 08-07-17 στις 19:42.
-
08-07-17, 21:39 Απάντηση: C++ Συντακτικά λάθοι; #2
Όπως πάντα, περίμενε να ακούσεις από κάποιον που ξέρει C++ για σωστές συμβουλές.
Το καλύτερο είναι να αλλάξεις την σχεδίαση των κλάσεων ώστε να μην έχεις πρόβλημα. Με τα παρόντα δεδομένα, μπορείς να δηλώσεις την κλάση στην αρχή για να ξεπεράσεις το circular.
Ας δούμε τώρα που είναι το πρόβλημα με τα παρόντα δεδομένα.
Κώδικας:In file included from map_node.h:2:0, from map.h:2, from map.cpp:1: trie_node.h:7:2: σφάλμα: ‘Map’ does not name a type Map map; ^~~
Αυτό όμως με τη σειρά του εισάγει το trie_node.h το οποίο έχει μέσα τα πεδία Map. Όπως ξέρεις, ο preprocessor το μόνο που κάνει είναι να ενώνει τα αρχεία οπότε το αποτέλεσμα είναι πριν την δήλωση της κλάσης Map να έχεις αναφορές σε κάτι που λέγεται Map.
Μία λύση θα ήταν να βάλεις "forward δηλώσεις" σε κάθε αρχείο .h οι οποίες να λένε πχ "class MapNode;" ώστε να δηλώνεται προσωρινά η κλάση και να μην κάνεις #include τα άλλα header files. Με αυτόν τον τρόπο όμως θα είχες ένα πρόβλημα. Στο trie_node.h έχεις ως πεδία απλές μεταβλητές τύπου Map το οποίο δεν θα έπαιζε γιατί δεν θα ήξερε ο compiler το μέγεθος της κλάσης και έτσι θα έπρεπε να αλλάξεις την κλάση σου να έχει δείκτες σε Map.
Αντί για αυτό όμως υπάρχει μια πιο εύκολη λύση. Θέλεις να μην καλείται το αρχείο trie_node.h μέσα στο αρχείο map.h. Οπότε μπορείς μέσα στο αρχείο map_node.h να αφαιρέσεις το include και να βάλεις μια forward δήλωση της TrieNode. Επειδή η κλάση MapNode έχει μόνο δείκτες σε TrieNode δεν θα έχεις πρόβλημα.
Κώδικας:diff -ur test.orig/map_node.h test/map_node.h --- test.orig/map_node.h 2017-07-08 17:07:56.998000000 +0300 +++ test/map_node.h 2017-07-08 21:26:15.044706580 +0300 @@ -1,6 +1,6 @@ #pragma once -#include "trie_node.h" +class TrieNode; class MapNode { private:
Κώδικας:% g++ -O2 -o main *cpp Main.cpp: In function ‘int main()’: Main.cpp:6:8: προειδοποίηση: ignoring return value of ‘int system(const char*)’, declared with attribute warn_unused_result [-Wunused-result] system("pause"); ~~~~~~^~~~~~~~~
"I like offending people, because I think people who get offended should be offended" - Linus Torvalds
"Παλιά είχαμε φτωχούς οι οποίοι ζούσανε σε φτωχογειτονιές. Τώρα, η οικονομικά δυσπραγούσα τάξη
κατέχει στέγες υποδεέστερης ποιότητας σε υποβαθμισμένα αστικά κέντρα" - George Carlin
Γα.... την πολιτική ορθότητα.
-
09-07-17, 02:03 Απάντηση: C++ Συντακτικά λάθοι; #3
Συγνώμη για τον τίτλο αλλά δεν γίνεται να τον κάνω επεξεργασία (ίσως να γίνεται αλλά δεν ξέρω πως).
Αυτό που δηλώνεις την κλάση είναι το ίδιο όπως κάνουμε και για τις συναρτήσεις, έτσι ώστε ο compiler να γνωρίζει
ότι κάπου ποιο κάτω θα συναντήσει αυτό που δηλώθηκε;
Κώδικας:int add(int a, int b) int main(){ add(1,2); return 0; } int add(int a, int b){ return a+b; }
Στην c δεν είχα τέτοια προβλήματα, ούτε στην java για αυτό θέλω να μάθω ακριβώς πως σκέφτεται ο compiler και πως πρέπει να οργανώνω τα αρχεία μου αλλιώς δεν μπορώ να προχωρήσω.Τελευταία επεξεργασία από το μέλος babaliaris : 09-07-17 στις 02:09.
-
09-07-17, 12:00 Απάντηση: C++ Συντακτικά λάθοι; #4
Κάτι τέτοιο. Αν δεν είχες τις κυκλικές εξαρτήσεις δεν θα χρειαζόταν να το κάνεις έτσι. Σκέψου ότι γράφεις κάπου "a =5;" χωρίς να έχεις δηλώσει πουθενά το a. Το ίδιο ήταν και αυτό. Είχες γράψει TrieNode *τάδε χωρίς να ορίζεται πουθενά τι είναι αυτό το TrieNode. Δηλώνοντας ότι είναι κλάση, ο compiler ξέρει πώς να προχωρήσει.
Το συγκεκριμένο (και άλλα παρόμοια) πρόβλημα θα το είχες και σε C απλά ίσως δεν έτυχε να το συναντήσεις. Όσον αφορά για πληροφορίες, το προφανές είναι να πάρεις ένα καλό βιβλίο για C++. Αν δεν θέλεις αυτή τη στιγμή να διαθέσεις χρήματα, υπάρχουν άπειροι οδηγοί στο διαδίκτυο για c++. Μια και δεν ασχολούμαι με C++ και ξέρω μόνο τα απολύτως βασικά (και ίσως ούτε αυτά), δεν γνωρίζω δυστυχώς να σου προτείνω κάτι καλό. Περίμενε να απαντήσει κάποιος άλλος.
Ένα link που θυμάμαι να έχω συναντήσει είναι αυτό που έχει καλά βιβλία για c++."I like offending people, because I think people who get offended should be offended" - Linus Torvalds
"Παλιά είχαμε φτωχούς οι οποίοι ζούσανε σε φτωχογειτονιές. Τώρα, η οικονομικά δυσπραγούσα τάξη
κατέχει στέγες υποδεέστερης ποιότητας σε υποβαθμισμένα αστικά κέντρα" - George Carlin
Γα.... την πολιτική ορθότητα.
-
09-07-17, 13:54 Απάντηση: C++ Συντακτικά λάθοι; #5
Ευχαριστώ πάρα πολύ για τις απαντήσεις σου. Για βιβλίο δεν διαθέτω χρήματα αυτήν την στιγμή αν και έχω ένα μικρό από την σχολή (Στην ουσία είναι για C απλώς σε κάνει και μια εισαγωγή στην C++) μου αλλά και αυτό τα βασικά σε μαθαίνει. Απ'όσο γνωρίζω δεν θα κάνουμε ποτέ c++ στην σχολή γιατί απ'οτι μας είπε ένας καθηγητής "Αφού μάθατε C και Java πλέον μπορείτε να μάθετε μόνοι σας όποια άλλη γλώσσα θέλετε". Τέλος πάντων πιστεύω σε μια βδομάδα θα είμαι αρκετά καλός προγραμματιστής σε C++.
-
09-07-17, 14:46 Απάντηση: C++ Συντακτικά λάθοι; #6
Σαν το βιβλίο δεν υπάρχει. Ένα βιβλίο από κάποιον που έχει διδακτική εμπειρία και μεταδοτικότητα (και που έχει γίνει proofread από δέκα άτομα πριν εκδοθεί) θα είναι πάντα απείρως καλύτερο από ένα οδηγό στο internet που έγραψε ένας τυχαίος σαν εμένα. Αν και θεωρώ πως πάντα πρέπει να "βρίσκουμε" χρήματα για αγορά βιβλίων, άνεργος είμαι και καταλαβαίνω πως είναι τα πράγματα. Οπότε θα αρκεστείς σε οδηγούς στο διαδίκτυο. Είσαι τυχερός ότι η c++ δεν βγήκε χτες και έτσι υπάρχουν πάρα πολλοί οδηγοί (απλά κάποιοι δεν είναι καλοί εννοείται). Ψάξε το μόνος σου μέχρι να μπει στο νήμα κάποιος που ασχολείται με το θέμα και έχει bookmarked οδηγούς για να σου προτείνει κάποιον καλό.
Δυστυχώς υπάρχουν πολλά τέτοια που είναι για C και απλά λένε δύο πράγματα για C++ ίσα ίσα για να μπορούν να πιάσουν και κανένα πελάτη που θέλει να μάθει C++. Τα περισσότερα δυστυχώς όχι μόνο δεν σου μαθαίνουν τίποτα για C++ αλλά σου κάνουν και κακό μάλιστα.
Σε μία εβδομάδα θα μάθεις το συντακτικό της C++ (και αυτό αμφιβάλλω μια και είναι τεράστια γλώσσα). Σε 10 χρόνια θα γίνεις "αρκετά καλός""I like offending people, because I think people who get offended should be offended" - Linus Torvalds
"Παλιά είχαμε φτωχούς οι οποίοι ζούσανε σε φτωχογειτονιές. Τώρα, η οικονομικά δυσπραγούσα τάξη
κατέχει στέγες υποδεέστερης ποιότητας σε υποβαθμισμένα αστικά κέντρα" - George Carlin
Γα.... την πολιτική ορθότητα.
-
09-07-17, 17:47 Απάντηση: C++ Συντακτικά λάθοι; #7
-
09-07-17, 19:36 Απάντηση: C++ Συντακτικά λάθοι; #8
Δεν υπάρχει περίπτωση να μην είχες πρόβλημα ειδικά στη C , δεν μπορείς να κάνεις include αρχείο το οποίο εξαρτάται από το ίδιο αρχείο που πας να κάνεις compile αυτή τη στιγμή .
Όπως και στην java δεν υπάρχει περίπτωση να χρησιμοποιήσεις package το οποίο εξαρτάται από το package που γράφεις εκείνη τη στιγμή .The 3 most dangerous things in the world are a computer technician with a software patch, a programmer with a screwdriver and a customer with an idea....
Εγκατάσταση Ubuntu και Joomla
-
10-07-17, 01:49 Απάντηση: C++ Συντακτικά λάθοι; #9
-
10-07-17, 12:15 Απάντηση: C++ Συντακτικά λάθοι; #10
Στον αντικειμενοστραφή όντως είναι πιο εύκολο να το συναντήσεις.
Κώδικας:struct node_wrong { int value; struct node_wrong next; }; struct node { int value; struct node *next; }; % cc -Wall -O2 -c tmp.c tmp.c:3:20: σφάλμα: field ‘next’ has incomplete type struct node_wrong next; ^~~~
"I like offending people, because I think people who get offended should be offended" - Linus Torvalds
"Παλιά είχαμε φτωχούς οι οποίοι ζούσανε σε φτωχογειτονιές. Τώρα, η οικονομικά δυσπραγούσα τάξη
κατέχει στέγες υποδεέστερης ποιότητας σε υποβαθμισμένα αστικά κέντρα" - George Carlin
Γα.... την πολιτική ορθότητα.
-
10-07-17, 16:43 Απάντηση: C++ Συντακτικά λάθοι; #11
Κατάλαβα, επειδή ο compiler προσπαθεί να καταχωρήσει χώρο στο stack για struct node_wrong next; πετάει σφάλμα γιατί δεν γνωρίζει ακόμα το μέγεθος του struct. Ενώ αν το δηλώσεις ως pointer, θα καταχωρίσεις την μνήμη εσύ αργότερα ενώ θα είναι πλέον γνωστό το μέγεθος του struct.
-
12-07-17, 13:54 Απάντηση: C++ Συντακτικά λάθη; #12
My 2 cents:
Εφόσον θέλεις περισσότερες πληροφορίες γράψε στο google "c++ forward declaration".
Τα πρώτα αποτελέσματα, ειδικά αυτά από το stackoverflow.com, είναι πολύ κατατοπιστικά.
Από τον κώδικα σου φαίνεται ότι έχεις επηρεαστεί από την java. Τα περισσότερα "this->" που γράφεις είναι αχρείαστα. Ο κώδικας θα κάνει compile και χωρίς αυτά. Μάλιστα είναι απίθανο να βρεις κώδικα από μη αρχάριο c++ programmer που να κάνει χρήση αυτού(εκτός αν πράγματι πρέπει να ξεχωρίσει μεταξύ class variable και local variable που ονομάζονται το ίδιο και έχουν το ίδιο τύπο.)
- - - Updated - - -
Και το 3 cent μου:
Η καλύτερη μέθοδος για να κάνεις initialize τα class/struct variables σε μια τιμή είναι να το κάνεις μέσω "initialization list" και όχι μέσα στον constructor.
(γράψε στο google τους όρους και θα καταλάβεις το γιατί).
Έτσι ο κώδικας σου αυτός:
Κώδικας:Map::Map() { this->head = nullptr; this->tail = nullptr; this->size = 0; }
Κώδικας:Map::Map() : head(nullptr), tail(nullptr), size(0) { }
Κώδικας:Map::Map() : head(nullptr) , tail(nullptr) , size(0) { }
Κάνω προσπάθεια να βάζω ; αντι για ?
-
12-07-17, 17:16 Απάντηση: C++ Συντακτικά λάθη; #13
Παρόμοια Θέματα
-
C++ Καταστρέφω σωστά την λίστα μου ή δημιουργώ memory leaks;
Από babaliaris στο φόρουμ Προγραμματισμός και γλώσσες προγραμματισμούΜηνύματα: 7Τελευταίο Μήνυμα: 13-07-17, 09:32
Bookmarks