Σε περίπτωση που κάθε τάξη έχει μια εικονική καταστροφέα;

ψήφοι
45

Java και C # υποστηρίζει την έννοια των κλάσεων που δεν μπορούν να χρησιμοποιηθούν ως μαθήματα βάση με το finalκαι sealedλέξεις-κλειδιά. Στην C ++, ωστόσο δεν υπάρχει κανένας καλός τρόπος για να αποφευχθεί μια τάξη από το να προέρχεται από την οποία αφήνει ο συντάκτης της κατηγορίας με ένα δίλημμα, θα πρέπει σε κάθε κατηγορία να έχει μια εικονική διάσπασης ή όχι;


Επεξεργασία: Από C ++ 11 αυτό δεν ισχύει πλέον, μπορείτε να καθορίσετε ότι μια τάξη είναι final.


Από τη μία πλευρά να βρει ένα αντικείμενο ένα εικονικό destructor σημαίνει ότι θα έχει μια vtableκαι, ως εκ τούτου καταναλώνουν 4 (ή 8 επί 64 μηχανές bit) επιπλέον bytes ανά-αντικείμενο για το vptr.

Από την άλλη πλευρά, αν κάποιος προέρχεται αργότερα από αυτή την κατηγορία και διαγράφει μια παραγόμενη κλάση μέσω ενός δείκτη προς την κλάση βάσης το πρόγραμμα θα ασαφώς καθοριζόμενες (λόγω της απουσίας ενός εικονικού destructor), και ειλικρινά βελτιστοποίηση για ένα δείκτη ανά αντικείμενο είναι γελοίος.

Από την πιασίματος χεριού που έχει ένα εικονικό destructor (αμφισβητήσιμα) διαφημίζει ότι αυτός ο τύπος προορίζεται να χρησιμοποιηθεί πολυμορφικώς.

Μερικοί άνθρωποι πιστεύουν ότι θα πρέπει να έχετε μια σαφή λόγο να μην χρησιμοποιήσει μια εικονική διάσπασης (όπως είναι η subtext του αυτό το ερώτημα ) και άλλοι λένε ότι θα πρέπει να γίνεται χρήση τους μόνο όταν έχετε λόγο να πιστεύετε ότι η τάξη σας είναι να προέρχεται από, τι κάνετε εσείς νομίζω?

Δημοσιεύθηκε 09/12/2008 στις 19:56
πηγή χρήστη
Σε άλλες γλώσσες...                            


8 απαντήσεις

ψήφοι
53

Κάθε αφηρημένη κλάση θα πρέπει είτε να έχουν,

  • προστατεύονται destructor, ή,
  • εικονική καταστροφέα.

Αν έχετε μια δημόσια μη εικονική διάσπασης, αυτό δεν είναι καλό, δεδομένου ότι επιτρέπει στους χρήστες να διαγράψετε μέσω του εν λόγω δείκτη παράγωγη αντικείμενο. Δεδομένου ότι, όπως όλοι γνωρίζουμε, αυτή είναι απροσδιόριστη συμπεριφορά.

Για μια κατηγορία που δεν προορίζονται να διαγράψετε μέσω ενός δείκτη σε αυτό, δεν υπάρχει κανένας απολύτως λόγος να έχουμε μια εικονική καταστροφέα. Δεν θα ήταν μόνο τα απόβλητα πόρους, αλλά το πιο σημαντικό είναι ότι θα δώσει στους χρήστες μια λάθος υπόδειξη. Απλά σκεφτείτε τι μίζερη λογική θα ήταν να δώσει std::iteratorμια εικονική καταστροφέα.

Απαντήθηκε 09/12/2008 στις 20:06
πηγή χρήστη

ψήφοι
26

Το ερώτημα είναι πραγματικά, θέλεις να επιβάλουν κανόνες σχετικά με το πώς θα πρέπει να χρησιμοποιείται τάξεις σας; Γιατί; Αν μια τάξη δεν έχει μια εικονική καταστροφέα, ο καθένας με τη χρήση της κατηγορίας γνωρίζει ότι δεν πρόκειται να προέρχονται από, και τι περιορισμοί ισχύουν αν το δοκιμάσετε ούτως ή άλλως. Δεν είναι αρκετά καλό;

Ή μήπως θα πρέπει να έχετε τον compiler για να ρίξει ένα σοβαρό σφάλμα αν κάποιος τολμήσει να κάνει κάτι που δεν είχαν προβλέψει;

Δώστε στους μαθητές ένα εικονικό καταστροφέα αν σκοπεύετε για τους ανθρώπους να αντλούν από αυτήν. Διαφορετικά δεν το κάνετε, και να υποθέσουμε ότι ο καθένας χρησιμοποιώντας τον κωδικό σας είναι αρκετά ευφυής για να χρησιμοποιήσετε τον κωδικό σας σωστά.

Απαντήθηκε 09/12/2008 στις 20:18
πηγή χρήστη

ψήφοι
8

Οχι! Οι Virtual καταστροφείς χρησιμοποιούνται μόνο όταν ένα αντικείμενο μιας παραγόμενης κλάσης διαγράφεται μέσω ενός δείκτη βάσης τάξη. Εάν τάξη σας δεν προορίζεται να χρησιμεύσει ως βάση σε αυτό το σενάριο, δεν κάνουν το καταστροφέα εικονική - θα πρέπει να στείλει ένα λάθος μήνυμα.

Απαντήθηκε 09/12/2008 στις 20:04
πηγή χρήστη

ψήφοι
4

Ελέγξτε αυτό το άρθρο από Herb Sutter :

Κατευθυντήρια γραμμή # 4: Μια κατηγορία καταστροφέα βάση θα πρέπει να είναι είτε δημόσια και εικονικά, ή προστατεύονται και nonvirtual.

Απαντήθηκε 10/12/2008 στις 14:08
πηγή χρήστη

ψήφοι
2

Θα ήθελα «όχι» στο γενικό ερώτημα. Δεν είναι κάθε τάξη χρειάζεται ένα. Εάν μπορείτε να ξέρετε ότι η τάξη δεν πρέπει ποτέ να κληρονομήσει από, τότε δεν υπάρχει καμία ανάγκη να επιβαρύνονται με το ανήλικο γενικά. Αλλά αν υπάρχει μια πιθανότητα, να είναι στην ασφαλή πλευρά και να θέσει ένα εκεί.

Απαντήθηκε 09/12/2008 στις 19:58
πηγή χρήστη

ψήφοι
0

Βάση τάξη γίνεται αφηρημένη κατηγορία, όταν περιέχει τουλάχιστον ένα καθαρό εικονική λειτουργία. Εάν βάσης δεν έχει μια εικονική διάσπασης και τα παράγωγα (που προέρχεται από τη βάση) έχει, τότε μπορείτε να καταστρέψουν με ασφάλεια ένα Προέρχεται αντικειμένου μέσω ενός Προέρχεται δείκτη αντικειμένου, αλλά όχι με βάση δείκτη αντικειμένου.

Απαντήθηκε 12/05/2010 στις 21:04
πηγή χρήστη

ψήφοι
0

Θα προσθέσω ότι υπήρξαν στιγμές που έχω έξυσε το κεφάλι μου για λίγο σε καταστροφείς να μην πάρει καλείται όταν ξέχασα μια εικονική στο γονέα ή το παιδί τάξη. Υποθέτω ότι ξέρουν να ψάξουν για αυτό τώρα όμως. :)

Κάποιος θα μπορούσε να υποστηρίξει ότι υπάρχουν φορές που η μητρική τάξη κάνει κάτι σε καταστροφέα της ότι ένα παιδί δεν πρέπει να κάνετε ... αλλά αυτό είναι πιθανώς ένας δείκτης κάτι δεν πάει καλά με τη δομή κληρονομιά σας έτσι κι αλλιώς.

Απαντήθηκε 09/12/2008 στις 20:14
πηγή χρήστη

ψήφοι
-3
include<iostream> using namespace std;

class base {
    public: base() {
        cout << "In base class constructor" << endl;
    }

    virtual ~base() {
        cout << "in base class destuctor" << endl;
    }
};

class derived : public base {
    public: derived() {
        cout << "in derived class constructor" << endl;
    }

    ~derived() {
        cout << "in derived class destructor" << endl;
    }
};

int main() {
    base *b; // pointer to the base
    class b = new derived; // creating the derived class object using new
    keyword;
    delete b;
    return 0;
}
Απαντήθηκε 01/01/2016 στις 13:52
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more