Δείκτες σε μέλη, ενώσεις
Διομήδης Σπινέλλης
Τμήμα Διοικητικής Επιστήμης και Τεχνολογίας
Οικονομικό Πανεπιστήμιο Αθηνών
dds@aueb.gr
Δείκτες σε μέλη κλάσεων
- Η C++ επιτρέπει τον ορισμό δεικτών σε μέλη (μεταβλητές ή συναρτήσεις)
μιας κλάσης.
Στο παρακάτω παράδειγμα η μεταβλητή coordptr ορίζεται ως δείκτης
σε ακέραιες μεταβλητές - μέλη - της κλάσης point.
class point {
public:
int x, y;
};
int point::*coordptr; // Pointer to one of the two point coordinates
Η μεταβλητή coordptr μπορεί να δείχνει στο μέλος x ή στο μέλος y.
- Η μεταβλητή μπορεί να λάβει αρχική τιμή με τη σύνταξη
var = &(class_name::member_name);
Παράδειγμα:
coordptr = &(point::x); // Coordptr points to the x coordinates
- Πρόσβαση στο αντίστοιχο μέλος μπορεί να υπάρξει μόνο με βάση
ένα πραγματικό αντικείμενο ή δείκτη της συγκεκριμένης κλάσης με
τους τελεστές .* και ->* αντίστοιχα.
Αριστερά από τον τελεστή γράφεται το αντικείμενο ή ο δείκτης της
κλάσης και δεξιά ο δείκτης στο μέλος της κλάσης.
- Το παρακάτω παράδειγμα ορίζει δύο μεταβλητές τύπου point και
δίνει αρχικές τιμές στα μέλη τους μέσω της coordptr η οποία αρχικά
δείχνει στα x και μετά στα y.
Έτσι, στο τέλος τυπώνει τις τιμές των σημείων ως (1, 2) και (10, 20).
#include <iostream.h>
class point {
public:
int x, y;
void print() { cout << x << "," << y << "\n"; }
};
main()
{
int point::*coordptr; // Pointer to a point coordinate
point p, p2;
coordptr = &(point::x); // Coordptr points to the x coordinates
p.*coordptr = 1;
p2.*coordptr = 10;
coordptr = &(point::y); // Coordptr now points to the y coordinates
p.*coordptr = 2;
p2.*coordptr = 20;
p.print();
p2.print();
return (0);
}
Δομές και ενώσεις
Η δήλωση μιας δομής στη C++ με τη μορφή:
struct s { ...
είναι μια συντομογραφία για τη δήλωση:
class s {public: ...
δηλαδή για μια κλάση της οποίας όλα τα μέλη είναι δημόσια.
Αντίστοιχα η δήλωση μιας ένωσης (union) επιτρέπει
τη χρήση του ίδιου χώρου από όλα τα μέλη της ένωσης.
Η C++ επιτρέπει τον ορισμό συναρτήσεων κατασκευής ως μέλη της ένωσης.
Με τη χρήση πολυμορφικών συναρτήσεων κατασκευής μπορεί κανείς να
αποδώσει αρχική τιμή σε οποιοδήποτε μέλος της ένωσης κατά την
αρχικοποίησή του.
Παράδειγμα:
union token {
char c;
int i;
double d;
token(char sc) {c = sc;}
token(int si) {i = si;}
token(double sd) {d = sd;}
};
void
f()
{
token a = 3.14; // Assign value to a.d
token b = 't'; // Assign value to b.c
}
Σε περίπτωση που θέλουμε να αποφύγουμε λάθη με την ανάθεση σε ένα
μέλος ενός τύπου και την ανάκτηση από ένα μέλος άλλου τύπου μπορούμε
να εμφωλιάσουμε την ένωση σε μια κλάση:
class token {
private:
enum e_type {CHAR, INT, DOUBLE} type;
union {
char c;
int i;
double d;
};
void check(e_type t) {if (type != t) error();}
public:
token(char sc) {c = sc; type = CHAR;}
token(int si) {i = si;} type = INT;}
token(double sd) {d = sd;} type = DOUBLE;}
int &cval() {check(CHAR); return c;}
int &ival() {check(INT); return i;}
int &dval() {check(DOUBLE); return d;}
token(char sc) {c = sc;}
token(int si) {i = si;}
token(double sd) {d = sd;}
};
void
f()
{
token a = 3.14; // Assign value to a.d
printf("%g\n", a.dval()); // Ok
printf("%d\n", a.ival()); // Check will fail
}