cpp:casting
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| cpp:casting [2026/04/24 11:46] – gthanos | cpp:casting [2026/04/24 12:28] (current) – [reinterpret_cast<>] gthanos | ||
|---|---|---|---|
| Line 5: | Line 5: | ||
| ===== static_cast<> | ===== static_cast<> | ||
| - | Ο συγκεκριμένος τελεστής μετατροπής τύπου δηλώνει ότι η αλλαγή του τύπου γίνεται κατά τη μεταγλώττιση. Ο // | + | Ο συγκεκριμένος τελεστής μετατροπής τύπου δηλώνει ότι η αλλαγή του τύπου γίνεται κατά τη μεταγλώττιση |
| ==== Παράδειγμα 1ο: Αριθμητικές Μετατροπές και Ακρίβεια ==== | ==== Παράδειγμα 1ο: Αριθμητικές Μετατροπές και Ακρίβεια ==== | ||
| Line 11: | Line 11: | ||
| Παρακάτω δίνουμε ένα παράδειγμα μετατροπής τύπου από int σε double για τον υπολογισμό μέσου όρου. Η μετατροπή από ένα βασικό τύπο σε ένα άλλο μπορεί να γίνει με static_cast εφόσον η μετατροπή είναι εφικτή. | Παρακάτω δίνουμε ένα παράδειγμα μετατροπής τύπου από int σε double για τον υπολογισμό μέσου όρου. Η μετατροπή από ένα βασικό τύπο σε ένα άλλο μπορεί να γίνει με static_cast εφόσον η μετατροπή είναι εφικτή. | ||
| - | <code static_cast_int2double.cpp> | + | < |
| #include < | #include < | ||
| Line 41: | Line 41: | ||
| Το static_cast επιτρέπει τη μετακίνηση στην ιεραρχία των κλάσεων, | Το static_cast επιτρέπει τη μετακίνηση στην ιεραρχία των κλάσεων, | ||
| - | <code static_cast_derived.cpp> | + | < |
| #include < | #include < | ||
| #include < | #include < | ||
| Line 93: | Line 93: | ||
| </ | </ | ||
| + | Γιατί να προτιμήσεις το static_cast αντί για το C-style cast (Derived*)b; | ||
| - | ====== dynamic_cast<> | + | - **Αποτροπή " |
| + | - **Δήλωση πρόθεσης: | ||
| - | ====== const_cast<> | + | <WRAP tip> |
| + | Χρησιμοποιήστε **static_cast** μόνο όταν | ||
| + | * η μετατροπή τύπου είναι απόλυτα λογική, | ||
| + | < | ||
| + | * είναι σίγουρο ότι το casting δεν θα αποτύχει σε καμία περίπτωση. Για παράδειγμα, | ||
| + | < | ||
| + | Derived derived(100); | ||
| + | Base& b = static_cast< | ||
| + | </ | ||
| + | |||
| + | Το **static_cast** εφαρμόζεται σχεδόν στα πάντα: | ||
| + | |||
| + | * **Κανονικούς Τύπους: | ||
| + | * **Pointers: | ||
| + | * **References**: | ||
| + | * **Enums:** Μετατροπή enums σε integers και αντίστροφα. | ||
| + | |||
| + | **Σημαντικό: | ||
| + | </ | ||
| + | |||
| + | ===== dynamic_cast<> | ||
| + | |||
| + | Το **dynamic_cast** είναι ο τύπος casting που εφαρμόζεται στον πολυμορφισμό. Το χρησιμοποιούμε όταν έχουμε έναν δείκτη προς μια βασική κλάση (Base*) και εξετάζουμε αν το αντικείμενο στο οποίο δείχνει είναι μια συγκεκριμένη παράγωγη κλάση (Derived*). | ||
| + | |||
| + | Ακολουθεί ένα σενάριο από ένα σύστημα πληρωμών, | ||
| + | |||
| + | <code cpp account_polymorphism.cpp> | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | // Η Base κλάση πρέπει να είναι πολυμορφική (να έχει τουλάχιστον μία virtual function) | ||
| + | class Account { | ||
| + | public: | ||
| + | virtual void withdraw(double amount) { | ||
| + | std::cout << " | ||
| + | } | ||
| + | virtual ~Account() {} // Απαραίτητος ΠΑΝΤΑ ο virtual destructor | ||
| + | }; | ||
| + | |||
| + | class SavingsAccount : public Account { | ||
| + | public: | ||
| + | void applyInterest() { | ||
| + | std::cout << " | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | class CheckingAccount : public Account { | ||
| + | public: | ||
| + | void printStatement() { | ||
| + | std::cout << " | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | void processAccount(Account* acc) { | ||
| + | // Θέλουμε να καλέσουμε την applyInterest(), | ||
| + | // Χρησιμοποιούμε dynamic_cast για να ελέγξουμε με ασφάλεια. | ||
| + | |||
| + | SavingsAccount* savings = dynamic_cast< | ||
| + | |||
| + | if (savings != nullptr) { | ||
| + | // Η μετατροπή πέτυχε! Το acc δείχνει όντως σε SavingsAccount. | ||
| + | savings-> | ||
| + | } else { | ||
| + | // Η μετατροπή απέτυχε. Το acc είναι κάτι άλλο (π.χ. CheckingAccount). | ||
| + | std::cout << " | ||
| + | } | ||
| + | } | ||
| + | |||
| + | int main() { | ||
| + | // Δημιουργούμε ένα vector από διαφορετικούς λογαριασμούς (Base pointers) | ||
| + | std:: | ||
| + | bank_vault.push_back(new SavingsAccount()); | ||
| + | bank_vault.push_back(new CheckingAccount()); | ||
| + | |||
| + | for (Account* acc : bank_vault) { | ||
| + | processAccount(acc); | ||
| + | delete acc; | ||
| + | } | ||
| + | |||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <WRAP tip 80% center round> | ||
| + | |||
| + | * **Runtime Check: | ||
| + | * **Ασφάλεια (Safety):** Αν χρησιμοποιούσαμε **static_cast** και το αντικείμενο ήταν τύπου CheckingAccount, | ||
| + | * **Πολυμορφισμός: | ||
| + | * **Δε λειτουργεί για κανονικούς τύπους: | ||
| + | |||
| + | </ | ||
| + | |||
| + | **Συνοπτικός Πίνακας** | ||
| + | |||
| + | ^ Τύπος | ||
| + | ^ Βασικοί Τύποι (int, double, κλπ) | ||
| + | ^ Pointers (Base* -> Derived*) | ||
| + | ^ References (Base& -> Derived& | ||
| + | ^ Enums | Ναι | ||
| + | |||
| + | |||
| + | ===== const_cast<> | ||
| + | |||
| + | Είναι ο μόνος τελεστής που μπορεί να προσθέσει ή να αφαιρέσει το const (ή το volatile) από μια μεταβλητή. | ||
| + | |||
| + | * **Γιατί να το κάνεις: | ||
| + | * **Ο Κίνδυνος: | ||
| + | |||
| + | <code cpp cost_cast.cpp> | ||
| + | void legacy_function(char* str) { | ||
| + | /* ... */ | ||
| + | } | ||
| + | |||
| + | const char* my_text | ||
| + | // legacy_function(my_text); | ||
| + | legacy_function(const_cast< | ||
| + | </ | ||
| ====== reinterpret_cast<> | ====== reinterpret_cast<> | ||
| + | |||
| + | Αυτός είναι ο πιο ισχυρός και επικίνδυνος τελεστής. Λέει στον compiler: " | ||
| + | |||
| + | **Τι κάνει: | ||
| + | |||
| + | **Προσοχή: | ||
| + | |||
| + | <code cpp reinterpret_cast.cpp> | ||
| + | long address = 0x7FFF1234; | ||
| + | // Ερμήνευσε αυτόν τον αριθμό ως διεύθυνση μνήμης ενός ακεραίου | ||
| + | int* p = reinterpret_cast< | ||
| + | </ | ||
| + | |||
| + | Ο συγκεκριμένος τελεστής μοιάζει με το type casting που γνωρίζουμε από τη γλώσσα C, διότι ο μεταγλωττιστής ακολουθεί χωρίς έλεγχο τις οδηγίες του προγραμματιστή. | ||
| + | |||
| + | |||
cpp/casting.1777031174.txt.gz · Last modified: 2026/04/24 11:46 by gthanos
