Προς το περιεχόμενο

Class σε Vector


Leon_13

Προτεινόμενες αναρτήσεις

Δημοσ.

έχω γραψει αυτό το κομμάτι κώδικα αλλά κάπου κολάει.

>
#include <vector>
...
...
class GeneralValues
{
	protected:
		char *Name;
		int Id;
		int RentDuration;
		float Price;
		float Price1;
	public:
		GeneralValues(char *v1, int v2, int v3, float v4, float v5)
		{
                               strcpy (Name,v1);
			Id = v2;
			RentDuration = v3;
			Price = v4;
			Price1 = v5;
		}
};

class Dvd : public GeneralValues
{
	protected:
		int TimeDuration;
	public:
		Dvd(char *t1,int t2,int t3,float t4,float t5,int t6) : GeneralValues(t1,t2,t3,t4,t5)
		{
			TimeDuration = t6;
		}
};
....
....
       vector <Dvd *> VectorDvd;
....
....
void SetValues()
{		
	VectorDvd.push_back(new Dvd("Lord", 1, 3, 2.0, 1.0,150));
}

 

ο compiler δεν χτυπάει αλλά όταν πάω να το τρέξω.

http://a.yfrog.com/img257/1364/errorww.jpg

Δημοσ.

>strcpy (Name,v1);

 

Απ'ότι φαίνεται από τον κώδικα που έχεις κάνει post, δεν κάνεις πουθενά allocate χώρο για το Name member με αποτέλεσμα η strcpy να προσπαθεί να κάνει copy σε random bytes και να crashάρει το πρόγραμμα.

 

Πρίν από την strcpy πρόσθεσε το εξής:

 

>Name = new char[strlen(v1)+1];

 

Επίσης καλο είναι να αλλάξεις τους constructors έτσι ώστε το πρώτο όρισμα αντί για char * να είναι const char *

 

Ο παρακάτω κώδικας κάνει compile και τρέχει χωρίς προβλήματα:

 

>#include <vector>
#include <cstring>

class GeneralValues
{
   protected:
       char *Name;
       int Id;
       int RentDuration;
       float Price;
       float Price1;

   public:
       GeneralValues (const char *v1, int v2, int v3, float v4, float v5)
       {
           Name = new char[strlen (v1) + 1];
           std::strcpy (Name, v1);
           Id = v2;
           RentDuration = v3;
           Price = v4;
           Price1 = v5;
       }
};

class Dvd : public GeneralValues
{
   protected:
       int TimeDuration;

   public:
       Dvd (const char *t1, int t2, int t3, float t4, float t5,
           int t6):GeneralValues (t1, t2, t3, t4, t5)
       {
           TimeDuration = t6;
       }
};

int main ()
{
   std::vector <Dvd *> VectorDvd;

   VectorDvd.push_back (new Dvd ("Lord", 1, 3, 2.0, 1.0, 150));
}

Δημοσ.

τώρα είναι οκ, σε ευχαριστώ πολύ για τον χρόνο σου.

 

πάντως χωρίς την διόρθωση μου έτρεξε σε άλλον υπολογιστή.

 

πια η διαφορά του char * με το const char * που μου πρότεινες;

Δημοσ.

πια η διαφορά του char * με το const char * που μου πρότεινες;

 

Όταν ένας pointer (πχ. const char *) ή ένα reference (πχ. const char &) είναι const qualified δεν επιτρέπει ο compiler την τροποποίηση της μνήμης στην οποία δείχνει (εμφανίζοντας σφάλμα).

 

Για παράδειγμα ο παρακάτω κώδικας πετάει σφάλμα:

 

>
void invalid(const char *);

int main() {
   invalid("noway");
}

void invalid(const char *s) {
   s[0] = '\0'; // ή *s = 0;
}

 

Εάν είχαμε παραλείψει το const στην παράμετρο της συνάρτησης invalid ο compiler δεν θα πετούσε σφάλμα (ίσως κάποιο warning) και όταν θα τρέχαμε το πρόγραμμα το πιθανότερο θα ήταν να crashάρει (Segmentation fault) διότι τα string literals ("noway" σε αυτήν την περίπτωση) τα δεσμεύει ο compiler σε μνήμη που δεν πρέπει να τροποποιηθεί.

 

πάντως χωρίς την διόρθωση μου έτρεξε σε άλλον υπολογιστή.

 

Σε αυτές τις περιπτώσεις λέμε ότι έχουμε undefined behavior, δηλαδή σε κάποιο μηχάνημα μπορεί να τρέξει κανονικά αλλά το πιθανότερο είναι να crashάρει. Το σίγουρο πάντως είναι ότι είναι τεράστιο λάθος η καταχώρηση δεδομένων σε τυχαίες θέσεις μνήμης και είναι πολύ συχνό λάθος που κάνουν οι νέοι προγραμματιστές.

 

Τέλος στον κώδικα που έδωσα στο προηγούμενο reply μου έχω παραλείψει τις δηλώσεις του copy constructor, destructor καθώς και του assignment operator για να μην κάνω περίπλοκο τον κώδικα. Συνήθως όμως όταν γίνεται δυναμική δέσμευση μνήμης στον constructor μίας κλάσης θα πρέπει να υλοποιούνται με προσοχή τα member functions που ανέφερα.

 

Ελπίζω να βοήθησα!

Δημοσ.

BTW εφοσον χρησιμοποιεις vector, γιατι δεν χρισιμοποιεις και string αντι του cstring (;) .

 

Επισης, αλλαξε το vector <Dvd *> VectorDvd με vector <Dvd> VectorDvd για να μην εχεις αλλα "περιεργα" προβληματα, γιατι με τετοιον compiler.... σιγουρα θα εχεις.

Δημοσ.

Δύο πραγματάκια,

 

1. Γιατί δε χρησιμοποιείς το std::string οπως λέει και ο Ευγένιος.

2. Από τη στιγμή που έχεις pointer se base class (Dvd*) κάνε και κανέναν destructor virtual, γιατί κάποια στιγμή θα την πατήσεις και θα ψάχνεσαι.

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...