This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
|
cpp:class_templates_specialization [2019/05/14 10:37] gthanos |
cpp:class_templates_specialization [2020/05/18 15:36] gthanos [Εξειδίκευση της κλάσης Box στην περίπτωση που η παράμετρος είναι δείτης σε χαρακτήρα] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Εξειδίκευση ενός υφιστάμενου template ====== | ====== Εξειδίκευση ενός υφιστάμενου template ====== | ||
| + | |||
| + | ===== Εξειδίκευση της κλάσης Box στην περίπτωση που η παράμετρος είναι δείκτης ===== | ||
| Συχνά είναι απαραίτητο να προδιαγράψουμε διαφορετική λειτουργικότητα σε ένα template με βάση τον τύπο των δεδομένων που θα εισαχθεί τελικά στην κλάση. Για παράδειγμα, | Συχνά είναι απαραίτητο να προδιαγράψουμε διαφορετική λειτουργικότητα σε ένα template με βάση τον τύπο των δεδομένων που θα εισαχθεί τελικά στην κλάση. Για παράδειγμα, | ||
| Line 77: | Line 79: | ||
| Παρακάτω παρατίθεται κώδικας ο οποίος χρησιμοποιεί την παραπάνω εξειδίκευση του // | Παρακάτω παρατίθεται κώδικας ο οποίος χρησιμοποιεί την παραπάνω εξειδίκευση του // | ||
| - | </code cpp BoxPtr.hpp> | + | <code cpp BoxPtrUsage.hpp> |
| - | #ifndef _BOXTPTR_HPP_ | + | #include < |
| - | #define _BOXTPTR_HPP_ | + | #include " |
| - | #include "Box.hpp" | + | #include "Student.hpp" |
| - | template< | + | using namespace |
| - | class Box< | + | |
| - | T *e; | + | |
| - | public: | + | |
| - | Box(); | + | |
| - | Box(T* e); | + | |
| - | Box(const Box< | + | |
| - | ~Box(); | + | |
| - | T* get() const; | + | |
| - | void set(T* e); | + | |
| - | template < | + | |
| - | friend | + | |
| - | Box< | + | |
| - | }; | + | |
| - | template | + | int main() { |
| - | Box<T*>::Box() { | + | int a=5; |
| - | | + | double d(4.23); |
| + | Student kate = {" | ||
| + | |||
| + | Box<int*> intBox(& | ||
| + | Box<double*> doubleBox(&d); | ||
| + | | ||
| + | Student* kate_ptr | ||
| + | |||
| + | cout << *kate_ptr << endl; | ||
| + | delete kate_ptr; | ||
| + | kate.setName(" | ||
| + | cout << kate << endl; | ||
| } | } | ||
| + | </ | ||
| - | template | + | <WRAP todo 80% center round> |
| - | Box< | + | Στον παραπάνω κώδικα αντικαταστήστε την |
| - | this->e = new T; | + | <code> |
| - | *(this-> | + | *** Error in `./ |
| - | } | + | ======= Backtrace: ========= |
| - | + | /lib/x86_64-linux-gnu/ | |
| - | template | + | / |
| - | Box<T*>:: | + | / |
| - | this->e = new T; | + | |
| - | | + | |
| - | } | + | |
| - | + | ||
| - | template < | + | |
| - | Box< | + | |
| - | std::cerr << "Box destructor: " << | + | |
| - | delete this-> | + | |
| - | } | + | |
| - | + | ||
| - | template < | + | |
| - | T* Box<T*>::get() const { | + | |
| - | T *ce = new T; | + | |
| - | *ce = *e; | + | |
| - | return ce; | + | |
| - | } | + | |
| - | + | ||
| - | template < | + | |
| - | void Box< | + | |
| - | if(this-> | + | |
| - | | + | |
| - | this->e = new T; | + | |
| - | *(this->e) = *e; | + | |
| - | } | + | |
| - | + | ||
| - | template < | + | |
| - | std:: | + | |
| - | T* ptr = t.get(); | + | |
| - | out << *ptr; | + | |
| - | delete ptr; | + | |
| - | return out; | + | |
| - | } | + | |
| - | + | ||
| - | template < | + | |
| - | Box< | + | |
| - | set(b.e); | + | |
| - | return *this; | + | |
| - | } | + | |
| - | #endif | + | |
| </ | </ | ||
| + | </ | ||
| - | <TODO tip 80% center round> | + | ===== Εξειδίκευση |
| - | Στον παραπάνω κώδικα αντικαταστήστε την | + | |
| - | </ | + | |
| Το παραπάνω παράδειγμα είναι ικανοποιητικό εάν περαστεί ως δείκτης ένα αντικείμενο τύπου **int* ** ή **Student* **, όμως δεν είναι ικανοποιητικό εάν περαστεί ένας δείκτης τύπου **char* ** που αντιπροσωπεύει ένα C string. Σε αυτή την περίπτωση δεν αρκεί να δεσμευθεί η μνήμη για ένα χαρακτήρα, | Το παραπάνω παράδειγμα είναι ικανοποιητικό εάν περαστεί ως δείκτης ένα αντικείμενο τύπου **int* ** ή **Student* **, όμως δεν είναι ικανοποιητικό εάν περαστεί ένας δείκτης τύπου **char* ** που αντιπροσωπεύει ένα C string. Σε αυτή την περίπτωση δεν αρκεί να δεσμευθεί η μνήμη για ένα χαρακτήρα, | ||
| Line 216: | Line 177: | ||
| #endif | #endif | ||
| </ | </ | ||
| + | |||
| + | Παράδειγμα κώδικα που χρησιμοποιεί την παραπάνω εξειδικευμένη κλάση **Box< | ||
| + | <code cpp BoxCharPtrUsage.cpp> | ||
| + | #include < | ||
| + | #include " | ||
| + | #include " | ||
| + | |||
| + | using namespace std; | ||
| + | |||
| + | int main() { | ||
| + | char greeting[64] = " | ||
| + | | ||
| + | Box< | ||
| + | | ||
| + | char* greeting_copy = greetingBox.get(); | ||
| + | cout << greeting_copy << endl; | ||
| + | delete greeting_copy; | ||
| + | | ||
| + | Box< | ||
| + | char* msg = msgBox.get(); | ||
| + | cout << msg << endl; | ||
| + | delete msg; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <WRAP todo 80% center round> | ||
| + | Στον παραπάνω κώδικα αντικαταστήστε την εντολή ''# | ||
| + | </ | ||