Κοινή χρήση τεχνολογίας

Λίστα αρχικοποίησης κατασκευαστή, στατικών μελών, φίλων, εσωτερικών κλάσεων [Κλάσεις και αντικείμενα (Μέρος 2)]

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

ΥΓ: Ο παρακάτω κώδικας δοκιμάστηκε στο περιβάλλον VS2022, πράγμα που δεν σημαίνει ότι όλοι οι μεταγλωττιστές μπορούν να τον περάσουν.
ΥΓ: Κανένας από τους κωδικούς δοκιμής δεν δείχνει τη δήλωση του αρχείου κεφαλίδας stdio.h. Προσθέστε το μόνοι σας όταν το χρησιμοποιείτε.

  

Εισαγάγετε την περιγραφή της εικόνας εδώ

                                           Αρχική σελίδα Blogger: LiUEEEEE
                                                στήλη C++
                                              Γ στήλη γλώσσας
                                            Στήλη δομή δεδομένων
                                            Στήλη αλγορίθμου ταξινόμησης
                                         Στήλη για κλασικά θέματα του Niuke

1. Λίστα αρχικοποίησης του κατασκευαστή

1.1 Κοιτάζοντας πίσω στον κατασκευαστή


Στο προηγούμενο blog μου

          Κατασκευή, καταστροφή, αντιγραφή [Τάξεις και αντικείμενα (Μέρος 2)]
Ο κατασκευαστής της κλάσης αναφέρεται. Λαμβάνοντας ως παράδειγμα την κλάση ημερομηνίας, η μέθοδος αρχικοποίησης είναι η εξής:

class Date
{
public:
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

Όπως φαίνεται στον παραπάνω κώδικα, χωρίς περαιτέρω μελέτη της C++, οι χρήστες συνήθως πιστεύουν ότι ο κώδικας στον κατασκευαστή είναι η προετοιμασία των μεταβλητών μελών της κλάσης, αλλά το γεγονός είναι ακριβώς το αντίθετο Στη C++, η κύρια δήλωση του κατασκευαστή ξεκινά μόνο Οι μεταβλητές μέλους δεν μπορούν να ονομαστούν αρχικοποίηση με την πραγματική έννοια, επειδή η προετοιμασία μπορεί να αρχικοποιηθεί μόνο μία φορά, ενώ ο κατασκευαστής μπορεί να εκχωρήσει τιμές σε μεταβλητές μέλους πολλές φορές, για παράδειγμα:

	Date(int year, int month, int day)
	{
		_year = year;
		_year += 1;
	}
  • 1
  • 2
  • 3
  • 4
  • 5

1.2 Λίστα αρχικοποίησης


Αυτή τη στιγμή, εισάγεται η λίστα αρχικοποίησης στη C++.
Η λίστα αρχικοποίησης είναι μια λίστα μελών δεδομένων που αρχίζει με ":" (άνω τελεία) και διαχωρίζεται με "," (κόμμα) Κάθε μεταβλητή μέλους ακολουθείται από μια αγκύλη και η τιμή που τοποθετείται στην αγκύλη είναι η αρχικοποιημένη τιμή, για παράδειγμα. :
	Date(int year, int month, int day)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
  • 1
  • 2
  • 3
  • 4
  • 5

πρέπει να γνωρίζετε είναι:

  1. Κάθε μεταβλητή μέλους μπορεί να εμφανιστεί μόνο μία φορά στη λίστα αρχικοποίησης (η αρχικοποίηση μπορεί να αρχικοποιηθεί μόνο μία φορά)
  2. Η κλάση περιέχει τα ακόλουθα μέλη, τα οποία πρέπει να τοποθετηθούν στη λίστα αρχικοποίησης για προετοιμασία:
    • Μεταβλητές μελών αναφοράς
    • Μεταβλητές μέλους προσαρμοσμένου τύπου (και ο προσαρμοσμένος τύπος δεν έχει προεπιλεγμένο κατασκευαστή: έναν κατασκευαστή χωρίς παραμέτρους, έναν πλήρως προεπιλεγμένο κατασκευαστή, έναν κατασκευαστή που δημιουργείται αυτόματα από το σύστημα)
    • const τροποποιημένες μεταβλητές μέλους

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

1.3 Συμβουλές για τη λίστα αρχικοποίησης


Κατά τη σύνταξη της λίστας αρχικοποίησης, η σειρά αρχικοποίησης των μεταβλητών μελών πρέπει να είναι συνεπής με τη σειρά δήλωσης στην κλάση, επειδή ο μεταγλωττιστής αρχικοποιεί τις μεταβλητές στη σειρά σύμφωνα με τη σειρά δήλωσης, εάν ο χρήστης δεν γράψει με τη σειρά περιττό πρόβλημα, όπως:
class A
{
public:
	A(int n)
		:_a2(n)
		,_a1(_a2)
	{}
	void Print()
	{
		cout << "_a1 = " << _a1 << endl;
		cout << "_a2 = " << _a2 << endl;
	}
private:
	int _a1;
	int _a2;
};

int main()
{
	A aa(100);
	aa.Print();

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

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



2. ρητή λέξη-κλειδί


Για τον κατασκευαστή, υπάρχει επίσης μια λειτουργία αφιερωμένηκατασκευαστής μιας παραμέτρουήΚατασκευαστής με πολλές παραμέτρους αλλά χωρίς προεπιλεγμένη τιμή για την πρώτη παράμετροΜετατροπή σιωπηρού τύπου, για παράδειγμα:
class Date
{
public:
	Date(int year)
		: _year(year)
	{}
	Date& operator=(const Date& d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
class Date
{
public:
	Date(int year, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
	Date& operator=(const Date& d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

Όταν εκχωρείτε περνώντας μια τιμή, για παράδειγμα:

	Date date(2024);
  • 1

Σε επίπεδο μεταγλωττιστή, το 2024 δεν εκχωρείται απευθείας στο αντικείμενο κλάσης που δημιουργήθηκε, αλλά το 2024 μετατρέπεται σε ένα προσωρινό αντικείμενο κλάσης μέσω σιωπηρής μετατροπής και στη συνέχεια εκχωρείται στο αντικείμενο κλάσης που πρέπει να αρχικοποιηθεί μέσω ενός τέτοιου αντικειμένου είναι απαραίτητο Το αρχικοποιημένο αντικείμενο κλάσης είναι Α και το προσωρινό αντικείμενο κλάσης είναι Β:

	Date A(2024);
	等价于
	Date A = B//B的值为2024
  • 1
  • 2
  • 3

Προκειμένου να αποφευχθεί η σιωπηρή μετατροπή, η C++ δημιούργησε τη ρητή λέξη-κλειδί Προσθέτοντας ρητή προτού μπορέσει ο κατασκευαστής να αποτρέψει τη σιωπηρή μετατροπή, για παράδειγμα:
	explicit Date(int year)
		: _year(year)
	{}
  • 1
  • 2
  • 3




3. στατικά μέλη

3.1 έννοια στατικού μέλους


Τα μέλη της κλάσης που δηλώνονται ως στατικά ονομάζονται στατικά μέλη της κλάσης. Οι στατικές μεταβλητές μελών πρέπει να αρχικοποιηθούν εκτός της κλάσης, για παράδειγμα:
class Date
{
public:
	Date(int year, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
	static int _i;
};

int Date::_i = 1;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

3.2 στατικά χαρακτηριστικά μελών


  1. Τα στατικά μέλη μοιράζονται όλα τα αντικείμενα κλάσης και δεν ανήκουν σε ένα συγκεκριμένο αντικείμενο. Αποθηκεύονται στη στατική περιοχή.
  2. Οι στατικές μεταβλητές μέλους πρέπει να ορίζονται εκτός της κλάσης Η στατική λέξη-κλειδί δεν προστίθεται κατά τον ορισμό.
  3. Τα στατικά μέλη κλάσης μπορούν να προσπελαστούν χρησιμοποιώντας το όνομα κλάσης::στατικό μέλος ή το αντικείμενο.στατικό μέλος
  4. Οι συναρτήσεις στατικών μελών δεν έχουν κρυφό αυτόν τον δείκτη και δεν μπορούν να έχουν πρόσβαση σε κανένα μη στατικό μέλος.
  5. Τα στατικά μέλη είναι επίσης μέλη της τάξης και περιορίζονται από προκριματικά δημόσιας, προστατευμένης και ιδιωτικής πρόσβασης.




4. Youyuan


Οι φίλοι παρέχουν έναν τρόπο να ξεπεράσετε την ενθυλάκωση και μερικές φορές παρέχουν ευκολία. Ωστόσο, οι φίλοι θα αυξήσουν τη σύζευξη και θα καταστρέψουν την ενθυλάκωση, επομένως οι φίλοι δεν πρέπει να χρησιμοποιούνται περισσότερες από μία φορές.

Οι φίλοι χωρίζονται σε: λειτουργίες φίλων και τάξεις φίλων

4.1 Λειτουργίες φίλου


Μια συνάρτηση φίλου σημαίνει ότι όταν μια συνάρτηση εκτός της κλάσης χρειάζεται πρόσβαση σε ένα ιδιωτικό μέλος της κλάσης, μπορεί να προσπελαστεί δηλώνοντας αυτήν τη συνάρτηση στην τάξη ως συνάρτηση φίλου της κλάσης, για παράδειγμα:
class Date
{
	friend void Print(Date& d);
public:
	Date(int year = 1, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};
void Print(Date& d)
{
	cout << d._year << " " << d._month << " " << d._day <<endl;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • Οι συναρτήσεις φίλου μπορούν να έχουν πρόσβαση σε ιδιωτικά και προστατευμένα μέλη μιας κλάσης, αλλά όχι σε συναρτήσεις μέλους της κλάσης
  • Οι συναρτήσεις φίλου δεν μπορούν να τροποποιηθούν με το const
  • Οι συναρτήσεις φίλου μπορούν να δηλωθούν οπουδήποτε στον ορισμό μιας κλάσης και δεν περιορίζονται από κριτήρια πρόσβασης κλάσης.
  • Μια συνάρτηση μπορεί να είναι μια συνάρτηση φίλου πολλών κλάσεων
  • Η αρχή της κλήσης συναρτήσεων φίλου είναι η ίδια με αυτή των συνηθισμένων συναρτήσεων.

4.2 Μαθήματα φίλων


Όταν μια κλάση θέλει να αποκτήσει πρόσβαση στα ιδιωτικά μέλη μιας άλλης κλάσης, μπορεί να δηλώσει αυτήν την κλάση ως φίλο στην τάξη στην οποία πρέπει να προσπελαστεί και, στη συνέχεια, μπορεί να έχει πρόσβαση στα ιδιωτικά μέλη της, για παράδειγμα:
class Time
{
	friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类
					   //中的私有成员变量
public:
	Time(int hour = 0, int minute = 0, int second = 0)
			: _hour(hour)
			, _minute(minute)
			, _second(second)
	{}
private:
	int _hour;
	int _minute;
	int _second;
};
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
			: _year(year)
			, _month(month)
			, _day(day)
	{}	
	void SetTimeOfDate(int hour, int minute, int second)
	{
		// 直接访问时间类私有的成员变量
		_t._hour = hour;
		_t._minute = minute;
		_t._second = second;
	}
private:
	int _year;
	int _month;
	int _day;
	Time _t;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • Οι φιλικές σχέσεις είναι μονόδρομες και μη ανταλλάξιμες. Για παράδειγμα, στην προαναφερθείσα κλάση Time και Date, εάν δηλώσετε την κλάση Date ως την κλάση φίλου στην κλάση Time, μπορείτε να αποκτήσετε απευθείας πρόσβαση στις ιδιωτικές μεταβλητές μέλους της κλάσης Time στην κλάση Date, αλλά θέλετε να πρόσβαση στις ιδιωτικές μεταβλητές μέλους της κλάσης Date στην κλάση Time No.
  • Η σχέση φίλου δεν μπορεί να είναι μεταβατική Εάν ο Γ είναι φίλος του Β και ο Β είναι φίλος του Α, δεν μπορεί να σημαίνει ότι ο Γ είναι φίλος του Α.




5. Εσωτερική τάξη


Η C++ υποστηρίζει τη δημιουργία μιας άλλης κλάσης μέσα σε μια κλάση, η οποία ονομάζεται εσωτερική κλάση Η εσωτερική κλάση είναι μια ανεξάρτητη κλάση και δεν είναι δυνατή η πρόσβαση στα μέλη της εσωτερικής κλάσης. . Η εξωτερική τάξη δεν έχει καμία ανώτερη πρόσβαση στην εσωτερική τάξη.
Και η εσωτερική τάξη είναι φυσικά φίλος της εξωτερικής τάξης, δηλαδή, η εσωτερική τάξη μπορεί να έχει πρόσβαση στα ιδιωτικά μέλη της εξωτερικής τάξης.

χαρακτηριστικό γνώρισμα:

  1. Οι εσωτερικές κλάσεις μπορούν να οριστούν ως δημόσιες, προστατευμένες ή ιδιωτικές σε εξωτερικές κλάσεις.
  2. Σημειώστε ότι οι εσωτερικές κλάσεις μπορούν να έχουν άμεση πρόσβαση στα στατικά μέλη σε εξωτερικές κλάσεις χωρίς να απαιτείται το όνομα αντικειμένου/κλάσης της εξωτερικής κλάσης.
  3. sizeof(external class)=external class, δεν έχει καμία σχέση με εσωτερικές κλάσεις.




6. Συμπέρασμα


Εισαγάγετε την περιγραφή της εικόνας εδώ

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