Teknologian jakaminen

Konstruktorin, staattisten jäsenten, ystävien, sisäisten luokkien alustusluettelo [Luokat ja objektit (osa 2)]

2024-07-12

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

PS: Seuraava koodi on testattu VS2022-ympäristössä, mikä ei tarkoita, että kaikki kääntäjät voisivat läpäistä sen.
PS: Mikään testikoodeista ei näytä otsikkotiedoston stdio.h ilmoitusta. Lisää se itse, kun käytät sitä.

  

Lisää kuvan kuvaus tähän

                                           Bloggerin kotisivu: LiUEEEEE
                                                C++ -sarake
                                              C-kielisarake
                                            Tietorakennesarake
                                            Lajittelualgoritmin sarake
                                         Kolumni Niuken klassisista aiheista

1. Rakentajan alustusluettelo

1.1 Katse taaksepäin rakentajaan


Edellisessä blogissani

          Rakentaminen, tuhoaminen, kopioiminen [Luokat ja esineet (osa 2)]
Luokan rakentaja mainitaan. Esimerkkinä päivämääräluokan alustusmenetelmä on seuraava:

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

Kuten yllä olevassa koodissa näkyy, ilman C++:n lisätutkimusta käyttäjät ajattelevat yleensä, että konstruktorissa oleva koodi on luokan jäsenmuuttujien alustus, mutta tosiasia on täysin päinvastainen C++:ssa rakentajan päälause vain alustuu Jäsenmuuttujia ei voi kutsua varsinaisessa merkityksessä alustukseksi, koska alustus voidaan alustaa vain kerran, kun taas rakentaja voi antaa arvoja jäsenmuuttujille useita kertoja, esimerkiksi:

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

1.2 Alustusluettelo


Tällä hetkellä C++:n alustusluettelo otetaan käyttöön.
Alustusluettelo on luettelo datajäsenistä, jotka alkavat kirjaimella ":" (kaksoispiste) ja erotetaan toisistaan ​​"," (pilkulla) jokaista jäsenmuuttujaa seuraa hakasulke, ja hakasulkeeseen asetettu arvo on esimerkiksi alustettu arvo. :
	Date(int year, int month, int day)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
  • 1
  • 2
  • 3
  • 4
  • 5

täytyy olla tietoinen on:

  1. Jokainen jäsenmuuttuja voi esiintyä alustusluettelossa vain kerran (alustaminen voidaan alustaa vain kerran)
  2. Luokka sisältää seuraavat jäsenet, jotka on sijoitettava alustusluetteloon alustusta varten:
    • Viitejäsenmuuttujat
    • Mukautetun tyypin jäsenmuuttujat (ja mukautetulla tyypillä ei ole oletuskonstruktoria: parametriton konstruktori, täysin oletuskonstruktori, järjestelmän automaattisesti luoma konstruktori)
    • const muokatut jäsenmuuttujat

Yllä mainitut mukautetut jäsenmuuttujat (ilman oletuskonstruktoria) tarkoittavat, että määritellyn mukautetun jäsenmuuttujan rakentaja on parametreilla varustettu konstruktori, ja parametrit on välitettävä ennen kuin se voidaan alustaa alustusluetteloa ei kirjoiteta, kääntäjä luo sen automaattisesti käyttäjälle. Jos mukautettujen jäsenmuuttujien alustus edellyttää kuitenkin parametrien osallistumista, järjestelmä ei välitä parametreja oletusarvoisesti, mikä johtaa yllä oleviin varotoimiin on vältettävä alustamisen syntymistä tarpeettomien ongelmien välttämiseksi myöhemmässä käytössä.

1.3 Vinkkejä alustusluetteloon


Alustuslistaa kirjoitettaessa jäsenmuuttujien alustusjärjestyksen tulee olla johdonmukainen luokan ilmoitusjärjestyksen kanssa, koska kääntäjä alustaa muuttujat peräkkäin ilmoitusjärjestyksen mukaan. Jos käyttäjä ei kirjoita järjestystä, se aiheuttaa turhaa vaivaa, kuten:
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

Lisää kuvan kuvaus tähän
Kun alustetaan yllä olevan kuvan mukaisesti, saadaan tuloksia, jotka eivät vastaa odotuksia, joten tällaisia ​​toimintoja on vältettävä sitä käytettäessä.



2. selkeä avainsana


Rakentajalle on myös omistettu toimintoYksiparametrinen konstruktoritaiKonstruktori, jossa on useita parametreja, mutta ei oletusarvoa ensimmäiselle parametrilleImplisiittinen tyyppimuunnos, esimerkiksi:
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

Kun määritetään antamalla arvo, esimerkiksi:

	Date date(2024);
  • 1

Kääntäjätasolla 2024 ei osoiteta suoraan luodulle luokkaobjektille, vaan 2024 muunnetaan väliaikaiseksi luokkaobjektiksi implisiittisen muunnoksen avulla ja osoitetaan sitten luokkaobjektille, joka on alustettava esimerkiksi sellaisen objektin kautta on välttämätön Alustettu luokkaobjekti on A ja väliaikainen luokkaobjekti on B:

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

Implisiittisen muuntamisen välttämiseksi C++ loi eksplisiittisen avainsanan ennen kuin rakentaja voi estää implisiittisen muuntamisen, esimerkiksi:
	explicit Date(int year)
		: _year(year)
	{}
  • 1
  • 2
  • 3




3. staattiset jäsenet

3.1 staattinen jäsenkonsepti


Staattisiksi ilmoitettuja luokan jäseniä kutsutaan staattisilla jäsenmuuttujiksi staattisiksi muunnetuiksi jäsenfunktioiksi. Staattiset jäsenmuuttujat on alustettava luokan ulkopuolella, esimerkiksi:
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 Jäsenten staattiset ominaisuudet


  1. Staattiset jäsenet ovat kaikkien luokkaobjektien yhteisiä, eivätkä ne kuulu tiettyyn objektiin. Ne tallennetaan staattiseen alueeseen.
  2. Staattiset jäsenmuuttujat on määriteltävä luokan ulkopuolella. Staattista avainsanaa ei lisätä luokassa.
  3. Luokan staattisiin jäseniin pääsee käyttämällä luokan nimi::staattinen jäsen tai objekti.staattinen jäsen
  4. Staattisissa jäsentoiminnoissa ei ole piilotettua tätä osoitinta, eivätkä ne voi käyttää ei-staattisia jäseniä.
  5. Staattiset jäsenet ovat myös luokan jäseniä, ja niitä rajoittavat julkiset, suojatut ja yksityiset käyttöoikeudet.




4. Youyuan


Ystävät tarjoavat tavan murtautua kapseloinnin läpi ja joskus tarjoavat mukavuutta. Ystävät kuitenkin lisäävät kytkentää ja tuhoavat kapseloinnin, joten ystäviä ei tule käyttää useammin kuin kerran.

Ystävät jaetaan: ystävätoimintoihin ja ystäväluokkiin

4.1 Ystävätoiminnot


Ystäväfunktio tarkoittaa, että kun luokan ulkopuolisen funktion on päästävä käsiksi luokan yksityisiin jäseniin, siihen päästään määrittämällä tämä funktio luokassa luokan ystäväfunktioksi, esimerkiksi:
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
  • Ystävätoiminnot voivat käyttää luokan yksityisiä ja suojattuja jäseniä, mutta eivät luokan jäsentoimintoja
  • Ystävätoimintoja ei voi muokata const
  • Ystäväfunktiot voidaan ilmoittaa missä tahansa luokkamäärittelyssä, eivätkä luokan pääsyn tarkenteet rajoita niitä.
  • Funktio voi olla useiden luokkien ystäväfunktio
  • Kaverifunktioiden kutsumisen periaate on sama kuin tavallisten funktioiden.

4.2 Ystäväkurssit


Kun luokka haluaa käyttää toisen luokan yksityisiä jäseniä, se voi ilmoittaa tämän luokan ystäväksi luokassa, johon on pääsy, ja sitten se voi käyttää yksityisiä jäseniään, esimerkiksi:
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
  • Ystäväsuhteet ovat yksisuuntaisia ​​ja ei-kommutatiivisia. Jos esimerkiksi yllä olevassa Time-luokassa ja Date-luokassa määrität Date-luokan ystäväluokakseen Time-luokassa, voit käyttää suoraan Date-luokan Time-luokan yksityisiä jäsenmuuttujia, mutta haluat käyttää Date-luokan yksityiset jäsenmuuttujat Time-luokassa.
  • Ystäväsuhde ei voi olla transitiivinen Jos C on B:n ystävä ja B on A:n ystävä, se ei voi tarkoittaa, että C on A:n ystävä.




5. Sisäinen luokka


C++ tukee toisen luokan luomista luokan sisällä, jota kutsutaan sisäiseksi luokkaksi. Sisäluokka ei kuulu ulompaan luokkaan, eikä sisäisen luokan jäseniin pääse käsiksi ulkoisen luokan objektien kautta. . Ulomalla luokalla ei ole ylivoimaista pääsyä sisäluokkaan.
Ja sisäluokka on luonnollisesti ulomman luokan ystävä, eli sisäluokka pääsee käsiksi ulomman luokan yksityisiin jäseniin.

ominaisuus:

  1. Sisäiset luokat voidaan määritellä julkisiksi, suojatuiksi tai yksityisiksi ulkoisissa luokissa.
  2. Huomaa, että sisäiset luokat voivat käyttää suoraan ulkoisten luokkien staattisia jäseniä ilman, että vaaditaan ulomman luokan objektin/luokan nimeä.
  3. sizeof(external class)=ulkoinen luokka, sillä ei ole mitään tekemistä sisäisten luokkien kanssa.




6. Johtopäätös


Lisää kuvan kuvaus tähän

  Kiitos, että katsoit alkuperäisen artikkelini.
  Tätä artikkelia käytetään pääasiassa henkilökohtaiseen oppimiseen ja tiedon jakamiseen. Oppimismatka on pitkä, jos siinä on virheitä.
  Jos tarvitset lainausta, ilmoita osoite.