குறிப்பு மற்றும் மதிப்பு வகைகளை நடைமுறைகளுக்கு அனுப்புதல். மதிப்பு மற்றும் குறிப்பு மூலம் அளவுருக்களை அனுப்புதல்

எனவே, Factorial(n) என்பது n எண்ணின் காரணியாலானதைக் கணக்கிடுவதற்கான செயல்பாடாக இருக்கட்டும். பின்னர், காரணி 1 என்பது 1 என்பதை நாம் அறிந்திருப்பதால், பின்வரும் சங்கிலியை நாம் உருவாக்கலாம்:

காரணி(4)=காரணம்(3)*4

காரணி(3)=காரணம்(2)*3

காரணி(2)=காரணம்(1)*2

ஆனால், எங்களிடம் n=1 காரணி சார்பு 1ஐத் தர வேண்டும் என்ற முனைய நிபந்தனை இல்லை என்றால், அத்தகைய கோட்பாட்டுச் சங்கிலி ஒருபோதும் முடிந்திருக்காது, மேலும் இது கால் ஸ்டாக் ஓவர்ஃப்ளோ பிழையாக இருந்திருக்கலாம் - கால் ஸ்டாக் ஓவர்ஃப்ளோ. கால் ஸ்டாக் என்றால் என்ன மற்றும் அது எவ்வாறு நிரம்பி வழிகிறது என்பதைப் புரிந்து கொள்ள, எங்கள் செயல்பாட்டின் சுழல்நிலை செயல்படுத்தலைப் பார்ப்போம்:

செயல்பாடு காரணி (n: முழு எண்): LongInt;

n=1 என்றால்

காரணி:=காரணம்(n-1)*n;

முடிவு;

நாம் பார்க்கிறபடி, சங்கிலி சரியாக வேலை செய்ய, ஒவ்வொரு அடுத்த செயல்பாடும் தன்னை அழைக்கும் முன், எல்லா உள்ளூர் மாறிகளையும் எங்காவது சேமிக்க வேண்டியது அவசியம், இதனால் சங்கிலி தலைகீழாக இருக்கும்போது, ​​​​முடிவு சரியாக இருக்கும் (கணக்கிடப்பட்ட மதிப்பு n-1 இன் காரணியாலானது n ஆல் பெருக்கப்படுகிறது). எங்கள் விஷயத்தில், ஒவ்வொரு முறையும் காரணிசார் செயல்பாடு தானாகவே அழைக்கப்படும் போது, ​​n மாறியின் அனைத்து மதிப்புகளும் சேமிக்கப்பட வேண்டும். ஒரு செயல்பாட்டின் உள்ளூர் மாறிகள் தன்னை மீண்டும் மீண்டும் அழைக்கும் போது சேமிக்கப்படும் பகுதி அழைப்பு அடுக்கு எனப்படும். நிச்சயமாக, இந்த ஸ்டாக் எல்லையற்றது அல்ல, சுழல்நிலை அழைப்புகள் தவறாகக் கட்டமைக்கப்பட்டால் தீர்ந்துவிடும். n=1 செயல்பாட்டின் அழைப்பு நின்றுவிடும் என்பதன் மூலம் எங்கள் எடுத்துக்காட்டின் மறு செய்கைகளின் இறுதித்தன்மை உறுதி செய்யப்படுகிறது.

மதிப்பு மற்றும் குறிப்பு மூலம் அளவுருக்களை அனுப்புதல்

இப்போது வரை சப்ரூட்டினில் உள்ள மதிப்பை மாற்ற முடியவில்லை உண்மையான அளவுரு(அதாவது, சப்ரூட்டினை அழைக்கும் போது குறிப்பிடப்படும் அளவுரு), மற்றும் சில பயன்பாட்டு பணிகளில் இது வசதியாக இருக்கும். அதன் உண்மையான இரண்டு அளவுருக்களின் மதிப்பை ஒரே நேரத்தில் மாற்றும் Val செயல்முறையை நினைவில் கொள்வோம்: முதலாவது சரம் மாறியின் மாற்றப்பட்ட மதிப்பு எழுதப்படும் அளவுரு, இரண்டாவது குறியீடு அளவுரு, இதில் பிழையான எண்ணிக்கை வகை மாற்றத்தின் போது தோல்வி ஏற்பட்டால் பாத்திரம் வைக்கப்படுகிறது. அந்த. ஒரு சப்ரூட்டின் உண்மையான அளவுருக்களை மாற்றக்கூடிய ஒரு வழிமுறை இன்னும் உள்ளது. அளவுருக்களை கடந்து செல்லும் பல்வேறு வழிகளுக்கு இது சாத்தியமாகும். இந்த முறைகளை இன்னும் விரிவாகப் பார்ப்போம்.

பாஸ்கலில் நிரலாக்கம்

மதிப்பு மூலம் அளவுருக்களை அனுப்புதல்

முக்கியமாக, இப்படித்தான் எல்லா அளவுருக்களையும் எங்கள் நடைமுறைகளுக்கு அனுப்பினோம். வழிமுறை பின்வருமாறு: ஒரு உண்மையான அளவுரு குறிப்பிடப்பட்டால், அதன் மதிப்பு சப்ரூட்டின் அமைந்துள்ள நினைவக பகுதிக்கு நகலெடுக்கப்படும், பின்னர், செயல்பாடு அல்லது செயல்முறை அதன் வேலையை முடித்த பிறகு, இந்த பகுதி அழிக்கப்படும். தோராயமாகச் சொன்னால், ஒரு சப்ரூட்டின் இயங்கும் போது, ​​அதன் அளவுருக்களின் இரண்டு பிரதிகள் உள்ளன: ஒன்று அழைப்பு நிரலின் நோக்கத்திலும், இரண்டாவது செயல்பாட்டின் நோக்கத்திலும்.

அளவுருக்களை அனுப்பும் இந்த முறை மூலம், சப்ரூட்டினை அழைக்க அதிக நேரம் எடுக்கும், ஏனெனில் அழைப்பைத் தவிர, அனைத்து உண்மையான அளவுருக்களின் அனைத்து மதிப்புகளையும் நகலெடுப்பது அவசியம். சப்ரூட்டினுக்கு அதிக அளவு தரவு அனுப்பப்பட்டால் (உதாரணமாக, அதிக எண்ணிக்கையிலான உறுப்புகளைக் கொண்ட வரிசை), தரவை உள்ளூர் பகுதிக்கு நகலெடுக்கத் தேவைப்படும் நேரம் குறிப்பிடத்தக்கதாக இருக்கும், மேலும் நிரல்களை உருவாக்கும்போது இது கணக்கில் எடுத்துக்கொள்ளப்பட வேண்டும். அவர்களின் செயல்திறனில் இடையூறுகளைக் கண்டறிதல்.

இந்த பரிமாற்ற முறை மூலம், உண்மையான அளவுருக்களை சப்ரூட்டினால் மாற்ற முடியாது, ஏனெனில் மாற்றங்கள் ஒரு தனிமைப்படுத்தப்பட்ட உள்ளூர் பகுதியை மட்டுமே பாதிக்கும், இது செயல்பாடு அல்லது செயல்முறை முடிந்ததும் வெளியிடப்படும்.

குறிப்பு மூலம் அளவுருக்களை அனுப்புதல்

இந்த முறை மூலம், உண்மையான அளவுருக்களின் மதிப்புகள் சப்ரூட்டினில் நகலெடுக்கப்படவில்லை, ஆனால் அவை அமைந்துள்ள நினைவகத்தில் உள்ள முகவரிகள் (மாறிகளுக்கான இணைப்புகள்) மாற்றப்படுகின்றன. இந்த வழக்கில், சப்ரூட்டின் ஏற்கனவே உள்ளூர் நோக்கத்தில் இல்லாத மதிப்புகளை மாற்றுகிறது, எனவே அனைத்து மாற்றங்களும் அழைப்பு நிரலில் தெரியும்.

ஒரு வாதம் குறிப்பு மூலம் அனுப்பப்பட வேண்டும் என்பதைக் குறிக்க, அதன் அறிவிப்புக்கு முன் var என்ற முக்கிய சொல் சேர்க்கப்படுகிறது:

செயல்முறை getTwoRandom(var n1, n2:Integer; range: Integer);

n1: = சீரற்ற (வரம்பு);

n2: = சீரற்ற (வரம்பு); முடிவு ;

var rand1, rand2: முழு எண்;

தொடங்கு getTwoRandom(rand1, rand2,10); WriteLn(rand1); WriteLn(rand2);

முடிவு.

இந்த எடுத்துக்காட்டில், இரண்டு மாறிகள் பற்றிய குறிப்புகள் உண்மையான அளவுருக்களாக getTwoRandom செயல்முறைக்கு அனுப்பப்படுகின்றன: rand1 மற்றும் rand2. மூன்றாவது உண்மையான அளவுரு (10) மதிப்பால் அனுப்பப்படுகிறது. முறையான அளவுருக்களைப் பயன்படுத்தி செயல்முறை எழுதுகிறது

"புள்ளிகளை வைப்பது" பற்றிய பாசாங்கு சிறுகுறிப்புக்கு நான் முன்கூட்டியே மன்னிப்பு கேட்கிறேன், ஆனால் நாங்கள் எப்படியாவது உங்களை கட்டுரையில் ஈர்க்க வேண்டும்)) என் பங்கிற்கு, சுருக்கம் இன்னும் உங்கள் எதிர்பார்ப்புகளை பூர்த்தி செய்வதை உறுதிப்படுத்த முயற்சிப்பேன்.

சுருக்கமாக நாம் என்ன பேசுகிறோம்

அனைவருக்கும் இது ஏற்கனவே தெரியும், ஆனால் 1C இல் முறை அளவுருக்களை எவ்வாறு அனுப்புவது என்பதை ஆரம்பத்தில் நான் உங்களுக்கு நினைவூட்டுகிறேன். அவை "குறிப்பு மூலம்" அல்லது "மதிப்பால்" அனுப்பப்படலாம். முதல் வழக்கில், அழைப்பின் புள்ளியில் உள்ள அதே மதிப்பை நாங்கள் முறைக்கு அனுப்புகிறோம், இரண்டாவதாக, அதன் நகல்.

இயல்பாக, 1C இல், வாதங்கள் குறிப்பு மூலம் அனுப்பப்படும், மேலும் ஒரு முறையின் உள்ளே உள்ள அளவுருவில் மாற்றங்கள் முறைக்கு வெளியே தெரியும். இங்கே, கேள்வியைப் பற்றிய கூடுதல் புரிதல் "அளவுருவின் மாற்றம்" என்ற வார்த்தையின் மூலம் நீங்கள் சரியாக என்ன புரிந்துகொள்கிறீர்கள் என்பதைப் பொறுத்தது. எனவே, இதன் பொருள் மறு ஒதுக்கீடு மற்றும் அதற்கு மேல் எதுவும் இல்லை. மேலும், பணியானது மறைமுகமாக இருக்கலாம், எடுத்துக்காட்டாக, வெளியீட்டு அளவுருவில் ஏதாவது ஒன்றை வழங்கும் இயங்குதள முறையை அழைப்பது.

ஆனால் நமது அளவுருவை குறிப்பு மூலம் அனுப்ப விரும்பவில்லை என்றால், அளவுருவிற்கு முன் ஒரு முக்கிய சொல்லைக் குறிப்பிடலாம். பொருள்

செயல்முறை மதிப்பு (மதிப்பு அளவுரு) அளவுரு = 2; EndProcedure Parameter = 1; மதிப்பு (அளவுரு); அறிக்கை (அளவுரு); // 1 ஐ அச்சிடும்

அனைத்தும் வாக்குறுதியளித்தபடி செயல்படுகின்றன - மாற்றுதல் (அல்லது மாறாக "மாற்றுதல்") அளவுரு மதிப்பு முறைக்கு வெளியே மதிப்பை மாற்றாது.

சரி, என்ன நகைச்சுவை?

நாம் பழமையான வகைகளை (சரங்கள், எண்கள், தேதிகள், முதலியன) அளவுருக்களாக அனுப்பத் தொடங்கும் போது சுவாரஸ்யமான தருணங்கள் தொடங்குகின்றன, ஆனால் பொருள்கள். ஒரு பொருளின் "ஆழமற்ற" மற்றும் "ஆழமான" பிரதிகள் போன்ற கருத்துகளும், சுட்டிகளும் (C++ சொற்களில் அல்ல, ஆனால் சுருக்கமான கைப்பிடிகளாக) செயல்படும் இடம் இதுதான்.

ஒரு பொருளை (உதாரணமாக, ஒரு மதிப்பு அட்டவணை) குறிப்பு மூலம் அனுப்பும் போது, ​​நாம் சுட்டிக்காட்டி மதிப்பை (ஒரு குறிப்பிட்ட கைப்பிடி) கடந்து செல்கிறோம், இது தளத்தின் நினைவகத்தில் பொருளை "பிடிக்கிறது". மதிப்பைக் கடந்து செல்லும் போது, ​​தளம் இந்த சுட்டியின் நகலை உருவாக்கும்.

வேறு வார்த்தைகளில் கூறுவதானால், ஒரு பொருளை குறிப்பு மூலம் அனுப்பினால், ஒரு முறையில் நாம் அளவுருவிற்கு "அரே" மதிப்பை ஒதுக்கினால், அழைப்பு புள்ளியில் நாம் ஒரு வரிசையைப் பெறுவோம். குறிப்பு மூலம் அனுப்பப்பட்ட மதிப்பின் மறு ஒதுக்கீடு அழைப்பு இடத்திலிருந்து தெரியும்.

செயல்முறை ProcessValue(அளவுரு) அளவுரு = புதிய வரிசை; இறுதிச் செயல்முறை அட்டவணை = புதிய மதிப்பு அட்டவணை; செயல்முறை மதிப்பு (அட்டவணை); அறிக்கை(மதிப்பு வகை(அட்டவணை)); // ஒரு வரிசையை வெளியிடும்

நாம் பொருளை மதிப்பின் மூலம் அனுப்பினால், அழைக்கும் கட்டத்தில் நமது மதிப்பு அட்டவணை இழக்கப்படாது.

பொருளின் உள்ளடக்கம் மற்றும் நிலை

மதிப்பைக் கடந்து செல்லும் போது, ​​முழு பொருளும் நகலெடுக்கப்படுவதில்லை, ஆனால் அதன் சுட்டிக்காட்டி மட்டுமே. பொருள் நிகழ்வு அப்படியே உள்ளது. குறிப்பால் அல்லது மதிப்பின் அடிப்படையில் நீங்கள் பொருளை எவ்வாறு கடந்து செல்கிறீர்கள் என்பது முக்கியமல்ல - மதிப்பு அட்டவணையை அழிப்பது அட்டவணையை அழிக்கும். இந்த சுத்தம் எல்லா இடங்களிலும் தெரியும், ஏனென்றால்... ஒரே ஒரு பொருள் மட்டுமே இருந்தது, அது எவ்வளவு சரியாக முறைக்கு அனுப்பப்பட்டது என்பது முக்கியமல்ல.

செயல்முறை ProcessValue(Parameter) Parameter.Clear(); இறுதிச் செயல்முறை அட்டவணை = புதிய மதிப்பு அட்டவணை; அட்டவணை. சேர்(); செயல்முறை மதிப்பு (அட்டவணை); அறிக்கை(அட்டவணை. அளவு()); // 0 ஐ வெளியிடும்

பொருள்களை முறைகளுக்கு அனுப்பும் போது, ​​தளம் சுட்டிகளுடன் செயல்படுகிறது (நிபந்தனை, C++ இலிருந்து நேரடி ஒப்புமைகள் அல்ல). ஒரு பொருள் குறிப்பு மூலம் அனுப்பப்பட்டால், அந்த பொருள் இருக்கும் 1C மெய்நிகர் இயந்திரத்தின் நினைவக செல் மற்றொரு பொருளால் மேலெழுதப்படலாம். ஒரு பொருள் மதிப்பால் அனுப்பப்பட்டால், சுட்டி நகலெடுக்கப்பட்டு, பொருளை மேலெழுதுவதால், அசல் பொருளுடன் நினைவக இருப்பிடத்தை மேலெழுத முடியாது.

அதே நேரத்தில், எந்த மாற்றமும் நிலைபொருள் (சுத்தம் செய்தல், பண்புகளைச் சேர்த்தல், முதலியன) பொருளையே மாற்றுகிறது, மேலும் பொருள் எப்படி, எங்கு மாற்றப்பட்டது என்பதற்கும் எந்தத் தொடர்பும் இல்லை. ஒரு பொருள் நிகழ்வின் நிலை மாறிவிட்டது, அதற்கு "குறிப்புகள்" மற்றும் "மதிப்புகள்" இருக்கலாம், ஆனால் நிகழ்வு எப்போதும் ஒரே மாதிரியாக இருக்கும். ஒரு பொருளை ஒரு முறைக்கு அனுப்புவதன் மூலம், முழு பொருளின் நகலையும் நாம் உருவாக்க மாட்டோம்.

இது எப்போதும் உண்மை, தவிர...

கிளையண்ட்-சர்வர் தொடர்பு

தளமானது சர்வர் அழைப்புகளை மிகவும் வெளிப்படையாக செயல்படுத்துகிறது. நாங்கள் ஒரு முறையை அழைக்கிறோம், மேலும் பேட்டைக்கு கீழ் இயங்குதளம் முறையின் அனைத்து அளவுருக்களையும் வரிசைப்படுத்துகிறது (சரமாக மாறும்), அவற்றை சேவையகத்திற்கு அனுப்புகிறது, பின்னர் வெளியீட்டு அளவுருக்களை கிளையண்டிற்குத் திருப்பித் தருகிறது, அங்கு அவை சீரழிக்கப்பட்டு வாழ்கின்றன. அவர்கள் எந்த சேவையகத்திற்கும் சென்றிருக்கவில்லை என்றால்.

உங்களுக்குத் தெரியும், அனைத்து இயங்குதளப் பொருட்களும் வரிசைப்படுத்தக்கூடியவை அல்ல. இங்குதான் வரம்பு வளர்கிறது: எல்லா பொருட்களையும் கிளையண்டிலிருந்து சர்வர் முறைக்கு அனுப்ப முடியாது. சீரியஸ் செய்ய முடியாத பொருளை நீங்கள் கடந்து சென்றால், மேடையில் கெட்ட வார்த்தைகளைப் பயன்படுத்தத் தொடங்கும்.

  • புரோகிராமரின் நோக்கங்களின் வெளிப்படையான அறிவிப்பு. முறை கையொப்பத்தைப் பார்ப்பதன் மூலம், எந்த அளவுருக்கள் உள்ளீடு மற்றும் வெளியீடு என்பதை நீங்கள் தெளிவாகக் கூறலாம். இந்த குறியீடு படிக்க மற்றும் பராமரிக்க எளிதானது
  • சேவையகத்தில் உள்ள "குறிப்பு மூலம்" அளவுருவில் மாற்றம் ஏற்பட, கிளையண்டின் அழைப்புப் புள்ளியில், பகட்டுரையின் தொடக்கத்தில் விவரிக்கப்பட்டுள்ள நடத்தையை உறுதி செய்வதற்காக, கிளையண்டிற்கான இணைப்பு வழியாக சேவையகத்திற்கு அனுப்பப்பட்ட அளவுருக்களை தளமே அவசியமாகத் திருப்பித் தரும். அளவுருவைத் திருப்பித் தரத் தேவையில்லை என்றால், போக்குவரத்து நெரிசல் ஏற்படும். தரவு பரிமாற்றத்தை மேம்படுத்த, வெளியீட்டில் நமக்குத் தேவையில்லாத அளவுருக்கள் மதிப்பு என்ற வார்த்தையுடன் குறிக்கப்பட வேண்டும்.

இரண்டாவது விடயம் இங்கு குறிப்பிடத்தக்கது. ட்ராஃபிக்கை மேம்படுத்த, அளவுரு மதிப்பு என்ற வார்த்தையுடன் குறிக்கப்பட்டிருந்தால், கிளையண்டிற்கு அளவுரு மதிப்பை இயங்குதளம் வழங்காது. இது எல்லாம் சிறந்தது, ஆனால் இது ஒரு சுவாரஸ்யமான விளைவுக்கு வழிவகுக்கிறது.

நான் ஏற்கனவே கூறியது போல், ஒரு பொருள் சேவையகத்திற்கு மாற்றப்படும் போது, ​​வரிசைப்படுத்தல் ஏற்படுகிறது, அதாவது. பொருளின் "ஆழமான" நகல் செய்யப்படுகிறது. மற்றும் ஒரு வார்த்தை இருந்தால் பொருள்பொருள் சேவையகத்திலிருந்து கிளையண்டிற்கு மீண்டும் செல்லாது. இந்த இரண்டு உண்மைகளையும் சேர்த்து பின்வருவனவற்றைப் பெறுகிறோம்:

&OnServerProcedureByLink(Parameter) Parameter.Clear(); EndProcedure &OnServerProcedureByValue(மதிப்பு அளவுரு) அளவுரு.Clear(); EndProcedure &OnClient Procedure ByValueClient(Value Parameter) Parameter.Clear(); EndProcedure &OnClient Procedure CheckValue() List1= New ListValues; பட்டியல்1.சேர் ("ஹலோ"); பட்டியல்2 = பட்டியல்1.நகல்(); பட்டியல்3 = பட்டியல்1.நகல்(); // பொருள் முழுவதுமாக நகலெடுக்கப்பட்டு, // சேவையகத்திற்கு மாற்றப்பட்டு, பின்னர் திரும்பும். // பட்டியலை அழிப்பது அழைப்பு புள்ளியில் தெரியும் ByRef(List1); // பொருள் முழுமையாக நகலெடுக்கப்பட்டது, // சேவையகத்திற்கு மாற்றப்பட்டது. அது திரும்பி வராது. // ByValue(List2) ஐ அழைக்கும் கட்டத்தில் பட்டியலை அழிப்பது தெரியவில்லை; // ஆப்ஜெக்ட் பாயிண்டர் மட்டும் நகலெடுக்கப்பட்டது // பட்டியலை அழிப்பது ByValueClient(List3)க்கான அழைப்பின் இடத்தில் தெரியும்; அறிக்கை(பட்டியல்1.அளவு()); அறிக்கை(பட்டியல்2. அளவு()); அறிக்கை(List3.Quantity()); இறுதிச் செயல்முறை

சுருக்கம்

சுருக்கமாக, அதை பின்வருமாறு சுருக்கமாகக் கூறலாம்:

  • குறிப்பு மூலம் கடந்து செல்வது முற்றிலும் வேறுபட்ட பொருளைக் கொண்ட ஒரு பொருளை "மேலெழுத" அனுமதிக்கிறது
  • மதிப்பைக் கடந்து செல்வது பொருளை "மேலெழுத" அனுமதிக்காது, ஆனால் பொருளின் உள் நிலையில் மாற்றங்கள் தெரியும், ஏனெனில் நாங்கள் அதே பொருள் நிகழ்வில் வேலை செய்கிறோம்
  • சேவையக அழைப்பைச் செய்யும்போது, ​​பொருளின் வெவ்வேறு நிகழ்வுகளுடன் வேலை செய்யப்படுகிறது, ஏனெனில் ஆழமான நகல் நிகழ்த்தப்பட்டது. முக்கிய வார்த்தை பொருள்சேவையக நிகழ்வு மீண்டும் கிளையண்ட் நிகழ்விற்கு நகலெடுக்கப்படுவதைத் தடுக்கும், மேலும் சேவையகத்தில் உள்ள பொருளின் உள் நிலையை மாற்றுவது கிளையண்டில் இதேபோன்ற மாற்றத்திற்கு வழிவகுக்காது.

இந்த எளிய விதிகளின் பட்டியல், “மதிப்பு மூலம்” மற்றும் “குறிப்பு மூலம்” அளவுருக்களை அனுப்புவது தொடர்பான சக ஊழியர்களுடனான மோதல்களைத் தீர்ப்பதை எளிதாக்கும் என்று நம்புகிறேன்.

பின்வரும் வழிகளில் ஒன்றில் ஒரு செயல்பாட்டிற்கு அளவுருக்கள் அனுப்பப்படலாம்:

மதிப்பின்படி வாதங்களை அனுப்பும் போது, ​​கம்பைலர் அனுப்ப வேண்டிய பொருளின் தற்காலிக நகலை உருவாக்கி, உள்ளூர் பொருட்களை சேமிப்பதற்காக நியமிக்கப்பட்ட ஸ்டாக் நினைவகத்தின் பகுதியில் வைக்கிறது. இந்த நகலில் அழைக்கப்படும் செயல்பாடு அசல் பொருளைப் பாதிக்காமல் செயல்படுகிறது. மதிப்பின்படி வாதங்களை எடுக்கும் செயல்பாடுகளின் முன்மாதிரிகள் பொருளின் முகவரியை அளவுருக்களாகக் காட்டிலும் பொருளின் வகையை வழங்குகின்றன. உதாரணமாக, செயல்பாடு

int GetMax(int, int);

மதிப்பின் அடிப்படையில் இரண்டு முழு எண் மதிப்புருக்களை எடுக்கிறது.

செயல்பாட்டிற்கு அசல் பொருளை மாற்றுவது அவசியமானால், குறிப்பு மூலம் அளவுருக்களை அனுப்புவது பயன்படுத்தப்படுகிறது. இந்த வழக்கில், பொருள் செயல்பாட்டிற்கு அனுப்பப்படவில்லை, ஆனால் அதன் முகவரி மட்டுமே. இவ்வாறு, குறிப்பு மூலம் அனுப்பப்படும் வாதங்களின் செயல்பாட்டின் உடலில் உள்ள அனைத்து மாற்றங்களும் பொருளைப் பாதிக்கின்றன. ஒரு செயல்பாடு ஒரு மதிப்பை மட்டுமே தர முடியும் என்பதைக் கருத்தில் கொண்டு, ஒரு பொருளின் முகவரியைப் பயன்படுத்துவது பெரிய அளவிலான தரவைக் கையாள மிகவும் திறமையான வழியாகும். கூடுதலாக, முகவரி மாற்றப்படுவதால், பொருள் அல்ல, ஸ்டாக் நினைவகம் கணிசமாக சேமிக்கப்படுகிறது.

சுட்டிகளைப் பயன்படுத்துதல்.

ரெஃபரன்ஷியல் பாஸிங் தொடரியல் என்பது பொருள் வகையை ஒரு வாதமாகப் பயன்படுத்துவதை உள்ளடக்குகிறது. உதாரணமாக, செயல்பாடு

இரட்டை பசை (நீண்ட& var1, int& var2);

லாங் மற்றும் இன்ட் வகை மாறிகளுக்கு இரண்டு குறிப்புகளைப் பெறுகிறது. ஒரு செயல்பாட்டிற்கு ஒரு குறிப்பு அளவுருவை அனுப்பும் போது, ​​கம்பைலர் தானாகவே செயல்பாட்டிற்கு ஒரு வாதமாக குறிப்பிடப்பட்ட மாறியின் முகவரியை அனுப்புகிறது. ஒரு செயல்பாட்டு அழைப்பில் ஒரு வாதத்திற்கு முன் ஒரு ஆம்பர்சண்ட் வைக்க வேண்டிய அவசியமில்லை. எடுத்துக்காட்டாக, முந்தைய செயல்பாட்டிற்கு, குறிப்பு மூலம் அழைப்பு அனுப்பும் அளவுருக்கள் இப்படி இருக்கும்:

பசை(var1, var2);

ஒரு சுட்டி மூலம் அளவுருக்களை அனுப்பும் போது ஒரு செயல்பாட்டு முன்மாதிரியின் எடுத்துக்காட்டு கீழே கொடுக்கப்பட்டுள்ளது:

வெற்றிடமான SetNumber(int*, long*);

கூடுதலாக, செயல்பாடுகள் ஒரு மாறியின் மதிப்பை மட்டுமல்ல, அதற்கு ஒரு சுட்டிக்காட்டி அல்லது குறிப்பையும் தரலாம். எடுத்துக்காட்டாக, முன்மாதிரியான செயல்பாடுகள்:

* int எண்ணிக்கை (int); &int அதிகரிப்பு();

int வகையின் முழு எண் மாறிக்கு முறையே ஒரு சுட்டி மற்றும் குறிப்பைத் திருப்பி அனுப்பவும். ஒரு செயல்பாட்டிலிருந்து ஒரு குறிப்பு அல்லது சுட்டியை திரும்பப் பெறுவது, குறிப்பிடப்பட்ட மாறியின் நோக்கத்திற்கு வெளியே இருந்தால் சிக்கல்களை ஏற்படுத்தலாம் என்பதை அறிந்து கொள்ளுங்கள். உதாரணத்திற்கு,

மாறிக்கு பதிலாக ஒரு பொருளின் முகவரியை அனுப்பும் திறன் செயல்பாட்டின் வேகத்தில் கவனிக்கப்படுகிறது, குறிப்பாக பெரிய பொருள்கள் பயன்படுத்தப்பட்டால், குறிப்பிட்ட அணிகளில் (பின்னர் விவாதிக்கப்படும்).

நீங்கள் ஒரு செயல்பாட்டிற்கு ஒரு பெரிய பொருளை அனுப்ப வேண்டும், ஆனால் அதன் மாற்றம் நோக்கம் இல்லை என்றால், நடைமுறையில் ஒரு நிலையான சுட்டிக்காட்டி அனுப்பப்படுகிறது. இந்த வகை அழைப்பில் const முக்கிய வார்த்தையின் பயன்பாடு அடங்கும், எடுத்துக்காட்டாக, செயல்பாடு

const int* FName(int* const Number)

int வகையின் நிலையான பொருளுக்கு ஒரு சுட்டியை ஏற்று திருப்பி அனுப்புகிறது. அழைக்கப்படும் செயல்பாட்டின் உடலில் அத்தகைய பொருளை மாற்றுவதற்கான எந்தவொரு முயற்சியும் கம்பைலரிடமிருந்து பிழை செய்தியை உருவாக்கும். நிலையான சுட்டிகளின் பயன்பாட்டை விளக்கும் உதாரணத்தைப் பார்ப்போம்.

#சேர்க்கிறது

int * const அழைப்பு (int * const);

int X = 13; int * pX = அழைப்பு (pX);

int* const அழைப்பு (int* const x)

//*x++; நீங்கள் பொருளை மாற்ற முடியாது! திரும்ப x;

மேலே உள்ள கான்ஸ்ட் பாயிண்டர் தொடரியலுக்குப் பதிலாக, அளவுருக்களைக் கடக்கும்போது மாற்றாக நீங்கள் const குறிப்புகளைப் பயன்படுத்தலாம், எடுத்துக்காட்டாக:

const int& FName (const int& Number)

நிலையான சுட்டிகள் போன்ற அதே பொருளைக் கொண்டவை.

#சேர்க்கிறது

const int& call(const int& x)

// நீங்கள் ஒரு பொருளை மாற்ற முடியாது!

ஒரு செயல்பாடு மற்றொன்றை அழைக்கும் போது, ​​அவற்றுக்கிடையேயான வழக்கமான தகவல்தொடர்பு முறையானது உலகளாவிய மாறிகள், திரும்பும் மதிப்புகள் மற்றும் அழைக்கப்படும் செயல்பாட்டின் அளவுருக்கள் ஆகியவற்றைப் பயன்படுத்துவதாகும்.

நிரலாக்க மொழிகள் துணை நிரலுக்கு அளவுருக்களை அனுப்ப இரண்டு முக்கிய வழிகளைக் கொண்டுள்ளன. முதலாவது மதிப்பைக் கடந்து செல்லுங்கள். அதைப் பயன்படுத்தும்போது, ​​உண்மையான அளவுருவின் (வாதம்) மதிப்பு சப்ரூட்டினின் முறையான அளவுருவில் நகலெடுக்கப்படுகிறது. இந்த வழக்கில், முறையான அளவுருவில் மாற்றங்கள் உண்மையான வாதத்தை பாதிக்காது.

சப்ரூட்டினுக்கு அளவுருக்களை அனுப்ப இரண்டாவது வழி குறிப்பு மூலம் கடந்து. பயன்படுத்தும் போது, ​​உண்மையான வாதத்தின் முகவரி முறையான அளவுருவில் நகலெடுக்கப்படும். இதன் பொருள், மதிப்பைக் கடந்து செல்வதைப் போலன்றி, முறையான அளவுருவின் மதிப்பில் ஏற்படும் மாற்றங்கள் உண்மையான வாதத்தின் மதிப்பில் அதே மாற்றங்களை ஏற்படுத்துகின்றன.

C மொழியில், உண்மையான மற்றும் முறையான அளவுருக்களை ஒப்பிடுவதற்கு ஒரே ஒரு வழி உள்ளது - மதிப்பின் மூலம் கடந்து செல்வது (குறிப்பு மூலம் அளவுருக்கள் C++ இல் கிடைக்கிறது). பாஸ்கலில் மதிப்பு மற்றும் குறிப்பு மூலம் கடந்து செல்கிறது. மற்ற முறைகள் உள்ளன (Fortran - copy-restore, Algol இல் - பெயர் மூலம் பரிமாற்றம்).

அளவுருக்களைக் கடப்பதற்கான எளிய வழி மதிப்பைக் கடந்து செல்வது. இந்த வழக்கில், உண்மையான அளவுருக்கள் கணக்கிடப்படுகின்றன, இதன் விளைவாக மதிப்புகள் அழைக்கப்படும் செயல்முறைக்கு அனுப்பப்படுகின்றன.

பாஸ்-பை-வேல்யூ முறை பின்வரும் வழியில் செயல்படுத்தப்படுகிறது:

    முறையான அளவுரு ஒரு உள்ளூர் மாறியாகக் கருதப்படுகிறது, எனவே அதற்கான நினைவகம் அழைக்கப்படும் செயல்பாட்டின் செயல்படுத்தும் பதிவில் ஒதுக்கப்படுகிறது, அதாவது. அடுக்கில்;

    அழைப்பு செயல்பாடு உண்மையான அளவுருக்களை மதிப்பிடுகிறது மற்றும் முறையான அளவுருக்களுக்கு ஒதுக்கப்பட்ட நினைவகத்தில் அவற்றின் மதிப்புகளை வைக்கிறது.

19.2. சி மொழியில் செயல்பாடுகளுக்கு அளவுருக்களை அனுப்புதல்

C மொழியில், ஒரு செயல்பாட்டை அழைக்கும் போது வாதங்கள் எப்போதும் மதிப்பு மூலம் அனுப்பப்படும், அதாவது. ஒரு செயல்பாட்டின் முறையான அளவுருக்களுக்கு அடுக்கில் இடம் ஒதுக்கப்படுகிறது, மேலும் உண்மையான வாதங்களின் மதிப்புகள் இந்த ஒதுக்கப்பட்ட இடத்தில் எழுதப்படும். செயல்பாடு அவற்றைப் பயன்படுத்துகிறது மற்றும் இந்த மதிப்புகளை அடுக்கில் மாற்றலாம். ஆனால் செயல்பாடு வெளியேறும் போது, ​​மாற்றப்பட்ட மதிப்புகள் இழக்கப்படும். சார்பு அழைக்கப்படும் போது உண்மையான வாதங்களாக குறிப்பிடப்பட்ட மாறிகளின் மதிப்புகளை அழைக்கப்படும் செயல்பாடு மாற்ற முடியாது.

void f(int k) ( k = -k; ) void main() ( int i = 1; f(i); printf("i = %d\n", i); // முடிவு: i = 1 )

குறிப்பு! வாதத்தின் நகல் செயல்பாட்டிற்கு அனுப்பப்பட்டது என்பதை நாம் நினைவில் கொள்ள வேண்டும். செயல்பாட்டிற்குள் என்ன நடக்கிறது என்பது அழைக்கப்படும் போது ஒரு வாதமாகப் பயன்படுத்தப்பட்ட மாறியின் மதிப்பைப் பாதிக்காது. இதன் காரணமாக, ஒரு செயல்பாட்டை அழைக்கும்போது, ​​மாறிகள் மட்டுமல்ல, மாறிகள் மற்றும் வெளிப்பாடுகளை உண்மையான வாதங்களாகக் குறிப்பிடலாம்.

19.3. செயல்பாடுகளுக்கு சுட்டிகளை அனுப்புதல்

செயல்பாட்டிற்கு உண்மையான அளவுருவின் மதிப்பை மாற்ற வேண்டுமானால் என்ன செய்வது? அத்தகைய அளவுருவை உலகளாவிய மாறியுடன் மாற்றுவது மிகவும் வெளிப்படையானது, ஆனால் சிறந்தது அல்ல. குறைபாடு என்னவென்றால், செயல்பாடுகளை அழைக்கும் போது கணக்கில் காட்டப்படாத பக்க விளைவுகள் காரணமாக தவறுகள் ஏற்படுவதற்கான வாய்ப்பு அதிகமாக உள்ளது.

தேவைப்பட்டால், அதற்கு அனுப்பப்பட்ட வாதங்களை மாற்ற செயல்பாட்டைப் பயன்படுத்தலாம். இந்த வழக்கில், வாதத்தின் மதிப்பை அல்ல, ஆனால் அதன் முகவரியின் மதிப்பை அழைக்கப்படும் செயல்பாட்டிற்கு ஒரு வாதமாக அனுப்ப வேண்டியது அவசியம், அதாவது. சுட்டி. செயல்பாடு வாதத்தின் முகவரிக்கு அனுப்பப்பட்டதால், அதன் உள் குறியீடு இந்த வாதத்தின் மதிப்பை மாற்ற முடியும்.

மற்ற வாதங்களைப் போலவே சுட்டியும் செயல்பாட்டிற்கு அனுப்பப்படுகிறது - மதிப்பின்படி. ஒரு முகவரியை அனுப்பும்போது, ​​அளவுருவை சுட்டிக்காட்டி வகைகளில் ஒன்றாக அறிவிக்க வேண்டும் என்பது தெளிவாகிறது.

செயல்பாடு வாதத்தின் நகலைப் பெறுவதால், அது சுட்டிக்காட்டியையே பாதிக்காது. ஆனால் அசல் வாதத்தின் மதிப்பை அணுக dereferencing operation * ஐப் பயன்படுத்தி, அது எங்கு இயக்கப்படுகிறதோ அதை எழுதலாம்.

பணி. இரண்டு மாறிகளின் மதிப்புகளை மாற்ற ஒரு செயல்பாட்டை எழுதவும் மற்றும் அதை செயல்பாட்டிலிருந்து அழைக்கவும்முக்கிய().

void swap(int *pa, int *pb) ( // சுட்டிக்காட்டி அளவுருக்கள்

*பா = *பிபி; // b ஐ a இல் வைக்கவும்

*pb = temp; // a வை b

வெற்றிட முக்கிய(வெற்றிடம்) (

int i = 10, j = 20;

printf("i மற்றும் j மதிப்புகளை மாற்றும் முன்: %d %d\n", i, j);

swap(&i, &j); // மாறிகள் i மற்றும் j முகவரிகளை அனுப்பவும்

swap() செயல்பாடு pa மற்றும் pb ஆல் சுட்டிக்காட்டப்பட்ட இரண்டு மாறிகளின் மதிப்புகளை மாற்றலாம், ஏனெனில் மாறிகளின் முகவரிகள் செயல்பாட்டிற்கு அனுப்பப்படுகின்றன, அவற்றின் மதிப்புகள் அல்ல. ஒரு செயல்பாட்டிற்குள், நிலையான சுட்டி செயல்பாடுகளைப் பயன்படுத்தி, நீங்கள் மாறிகளின் உள்ளடக்கங்களை அணுகலாம் மற்றும் அவற்றின் மதிப்புகளை பரிமாறிக்கொள்ளலாம்.

குறிப்பு! சுட்டிக்காட்டி அளவுருக்களைப் பயன்படுத்தும் எந்தச் செயல்பாடும் & முகவரி ஆபரேட்டரைப் பயன்படுத்தி அழைக்கப்படும் போது வாதங்களின் முகவரிகளை அனுப்ப வேண்டும்.

சுட்டிக்காட்டி வாதங்களுடன் ஒரு செயல்பாட்டை அழைக்கும் போது, ​​மாறியின் முகவரியை ஒரு அளவுருவாக குறிப்பிட வேண்டிய அவசியமில்லை. அதற்குப் பதிலாக, அத்தகைய முகவரியைக் கொண்ட ஒரு சுட்டியின் மதிப்பை நீங்கள் அனுப்பலாம்.

வெற்றிட முக்கிய(வெற்றிடம்) (

int i = 10, j = 20;

int *pi = &i, *pj =

printf("i மற்றும் j மதிப்புகளை மாற்றும் முன்: %d %d\n", i, j);

swap(pi, pj); // மாறிகள் i மற்றும் j முகவரிகளை அனுப்பவும்

printf("i மற்றும் j மதிப்புகளை மாற்றிய பின்: %d %d\n", i, j);

இங்கே நாம் சாதாரண மாறிகளைப் போலவே சுட்டிகளுடன் வேலை செய்கிறோம் - ஒதுக்கீட்டு ஆபரேட்டரைப் பயன்படுத்தி அவர்களுக்கு மதிப்புகளை அனுப்புகிறோம், பின்னர் அவற்றை செயல்பாடுகளுக்கு அனுப்புகிறோம்.

முடிவுரை:அழைப்பு செயல்பாட்டில் மாறிகளை மாற்ற அழைக்கப்பட்ட செயல்பாடு பயன்படுத்தப்பட்டால், அளவுருக்களாக அது தேவையான மாறிகள் அல்ல, ஆனால் அவற்றின் முகவரிகள் அல்லது சுட்டிகளை அனுப்ப வேண்டும்.

பணி. இரண்டு எதிர்மறை எண்களின் கூட்டுத்தொகையைக் கணக்கிட இரண்டு செயல்பாடுகளை எழுதவும் மற்றும் அவற்றைச் செயல்பாட்டிலிருந்து அழைக்கவும்முக்கிய(). உள்ளீட்டு தரவு செயல்பாடுகளில் உள்ளிடப்பட வேண்டும்முக்கிய(). முதல் செயல்பாடு குறிப்பிட்ட மதிப்பை வழங்க வேண்டும். இரண்டாவது செயல்பாட்டில், மூலத் தரவின் சரியான கட்டுப்பாட்டை உறுதிப்படுத்தவும். செயல்பாடு, கொடுக்கப்பட்ட மதிப்பைக் கணக்கிடுவதோடு, மூலத் தரவின் சரியான தன்மையைக் குறிக்கும்.

int sum1(int a, int b) (

int sum2(int a, int b, int *sum) (

என்றால் (a >= 0 || b >= 0)

திரும்ப 0; // தவறான தரவின் அடையாளம்

திரும்ப 1; // சரியான தரவின் அடையாளம்

வெற்றிட முக்கிய(வெற்றிடம்) (

scanf(“%d %d”, &x, &y);

printf("தொகை 1 = %d\n", sum1(x,y));

என்றால் (தொகை2(x,y,&கள்) == 1)

printf("தொகை 2 = %d\n", s);

printf("தவறான தரவு!\n");

நான் C++ இல் நிரலாக்கத் தொடங்கி, புத்தகங்கள் மற்றும் கட்டுரைகளை தீவிரமாகப் படித்தபோது, ​​நான் எப்போதும் அதே ஆலோசனையைக் கண்டேன்: செயல்பாட்டில் மாறாத செயல்பாட்டிற்கு சில பொருளை அனுப்ப வேண்டும் என்றால், அது எப்போதும் அனுப்பப்பட வேண்டும். ஒரு நிலையான குறிப்பால்(பிபிஎஸ்கே), ஒரு பழமையான வகை அல்லது அவற்றின் அளவை ஒத்த ஒரு கட்டமைப்பை நாம் அனுப்ப வேண்டிய நிகழ்வுகளைத் தவிர. ஏனெனில் சி ++ இல் 10 ஆண்டுகளுக்கும் மேலாக நிரலாக்கத்தில், இந்த ஆலோசனையை நான் அடிக்கடி சந்தித்திருக்கிறேன் (நானே அதை ஒன்றுக்கு மேற்பட்ட முறை கொடுத்துள்ளேன்), இது நீண்ட காலமாக எனக்குள் "உறிஞ்சப்பட்டுள்ளது" - ஒரு மாறிலியைக் குறிப்பிடுவதன் மூலம் எல்லா வாதங்களையும் தானாகவே கடந்து செல்கிறேன். . ஆனால் காலப்போக்கில், 7 ஆண்டுகள் கடந்துவிட்டன, அதன் நகர்வு சொற்பொருளுடன் C++11 எங்களிடம் உள்ளது, இது தொடர்பாக நல்ல பழைய கோட்பாட்டை கேள்விக்குட்படுத்தும் குரல்களை நான் மேலும் மேலும் கேட்கிறேன். மாறிலியைக் குறிப்பிடுவது கடந்த காலத்தின் ஒரு விஷயம், இப்போது அது அவசியம் என்று பலர் வாதிடத் தொடங்கியுள்ளனர் மதிப்பைக் கடந்து செல்லுங்கள்(PPZ). இந்த உரையாடல்களுக்குப் பின்னால் என்ன இருக்கிறது, இவை அனைத்திலிருந்தும் நாம் என்ன முடிவுகளை எடுக்க முடியும், இந்த கட்டுரையில் விவாதிக்க விரும்புகிறேன்.

புத்தக ஞானம்

நாம் எந்த விதியைக் கடைப்பிடிக்க வேண்டும் என்பதைப் புரிந்து கொள்ள, புத்தகங்களுக்குத் திரும்புவதை நான் பரிந்துரைக்கிறேன். புத்தகங்கள் ஒரு சிறந்த தகவல் மூலமாகும், அதை நாம் ஏற்றுக்கொள்ள வேண்டிய அவசியமில்லை, ஆனால் இது நிச்சயமாகக் கேட்கத் தகுந்தது. நாம் வரலாற்றுடன், தோற்றத்துடன் தொடங்குவோம். பிபிஎஸ்சியின் முதல் மன்னிப்புக் கேட்டவர் யார் என்பதை நான் கண்டுபிடிக்க முடியாது, பிபிஎஸ்சியைப் பயன்படுத்துவதில் தனிப்பட்ட முறையில் என்மீது மிகப் பெரிய தாக்கத்தை ஏற்படுத்திய புத்தகத்தை உதாரணமாக தருகிறேன்.

மேயர்ஸ்

சரி, இங்கே எங்களிடம் ஒரு வகுப்பு உள்ளது, அதில் அனைத்து அளவுருக்களும் குறிப்பு மூலம் அனுப்பப்படுகின்றன, இந்த வகுப்பில் ஏதேனும் சிக்கல்கள் உள்ளதா? துரதிருஷ்டவசமாக, உள்ளது, இந்த பிரச்சனை மேற்பரப்பில் உள்ளது. எங்கள் வகுப்பில் 2 செயல்பாட்டு உட்பொருள்கள் உள்ளன: முதலாவது பொருள் உருவாக்கும் கட்டத்தில் ஒரு மதிப்பை எடுக்கும், இரண்டாவது முன்பு அமைக்கப்பட்ட மதிப்பை மாற்ற உங்களை அனுமதிக்கிறது. எங்களிடம் இரண்டு நிறுவனங்கள் உள்ளன, ஆனால் நான்கு செயல்பாடுகள் உள்ளன. இப்போது நாம் 2 ஒத்த உறுப்புகளை வைத்திருக்க முடியாது என்று கற்பனை செய்து பாருங்கள், ஆனால் 3, 5, 6, பிறகு என்ன? பின்னர் நாம் கடுமையான குறியீடு வீக்கத்தை சந்திப்போம். எனவே, ஏராளமான செயல்பாடுகளை உருவாக்காமல் இருக்க, அளவுருக்களில் உள்ள இணைப்புகளை முற்றிலுமாக கைவிட ஒரு திட்டம் இருந்தது:

டெம்ப்ளேட் கிளாஸ் ஹோல்டர் (பொது: வெளிப்படையான ஹோல்டர்(டி மதிப்பு): m_Value(நகர்வு(மதிப்பு)) () வெற்றிடமான தொகுப்புமதிப்பு(T மதிப்பு) (m_Value = நகர்வு(மதிப்பு); ) const T& value() const noexcept ( m_Value; ) தனிப்பட்ட: T m_Value);

உடனடியாக உங்கள் கண்களைக் கவரும் முதல் நன்மை என்னவென்றால், குறிப்பிடத்தக்க அளவு குறைவான குறியீடு உள்ளது. கான்ஸ்ட் மற்றும் & (அவர்கள் நகர்வைச் சேர்த்திருந்தாலும்) அகற்றப்பட்டதன் காரணமாக, முதல் பதிப்பை விட இது குறைவாகவே உள்ளது. ஆனால் மதிப்பைக் கடந்து செல்வதை விட குறிப்பு மூலம் கடந்து செல்வது அதிக பலனைத் தரும் என்று நாம் எப்போதும் கற்பிக்கப்படுகிறோம்! C++11 க்கு முன்பு இப்படித்தான் இருந்தது, இப்போதும் எப்படி இருக்கிறது, ஆனால் இப்போது இந்தக் குறியீட்டைப் பார்த்தால், முதல் பதிப்பை விட இங்கே நகலெடுப்பது அதிகம் இல்லை என்பது தெரியும். டி ஒரு மூவ் கன்ஸ்ட்ரக்டரைக் கொண்டுள்ளது. அந்த. PPSC தானே PPZ ஐ விட வேகமாக இருக்கும், ஆனால் குறியீடு எப்படியாவது அனுப்பப்பட்ட குறிப்பைப் பயன்படுத்துகிறது, மேலும் பெரும்பாலும் இந்த வாதம் நகலெடுக்கப்படுகிறது.

இருப்பினும், இது முழு கதையல்ல. முதல் விருப்பத்தைப் போலல்லாமல், எங்களிடம் நகலெடுப்பது மட்டுமே உள்ளது, இங்கே நாம் இயக்கத்தையும் சேர்க்கிறோம். ஆனால் நகர்த்துவது மலிவான செயல், இல்லையா? இந்தத் தலைப்பில், நாங்கள் பரிசீலிக்கும் மேயர்ஸ் புத்தகத்தில் ஒரு அத்தியாயம் ("உருப்படி 29") உள்ளது: "நகர்வு செயல்பாடுகள் தற்போது இல்லை, மலிவானவை மற்றும் பயன்படுத்தப்படவில்லை என்று வைத்துக்கொள்வோம்." முக்கிய யோசனை தலைப்பிலிருந்து தெளிவாக இருக்க வேண்டும், ஆனால் உங்களுக்கு விவரங்கள் தேவைப்பட்டால், அதைப் படிக்க மறக்காதீர்கள் - நான் அதில் வசிக்க மாட்டேன்.

முதல் மற்றும் கடைசி முறைகளின் முழு ஒப்பீட்டு பகுப்பாய்வை நடத்துவது இங்கே பொருத்தமானதாக இருக்கும், ஆனால் நான் புத்தகத்திலிருந்து விலக விரும்பவில்லை, எனவே மற்ற பிரிவுகளுக்கான பகுப்பாய்வை ஒத்திவைப்போம், இங்கே ஸ்காட்டின் வாதங்களை நாங்கள் தொடர்ந்து பரிசீலிப்போம். எனவே, மூன்றாவது விருப்பம் இரண்டாவது விருப்பத்தை விட குறைவாக உள்ளது என்பதைத் தவிர, நவீன குறியீட்டில் PPSC ஐ விட PPZ இன் நன்மையாக ஸ்காட் என்ன பார்க்கிறார்?

அவர் ஒரு மதிப்பைக் கடக்கும் விஷயத்தில், அதாவது. சிலர் இப்படி அழைக்கிறார்கள்: ஹோல்டர் ஹோல்டர்(ஸ்ட்ரிங்("மீ")); , PPSC உடனான விருப்பம் நகலெடுக்கும், மற்றும் PPZ உடன் உள்ள விருப்பம் நமக்கு இயக்கத்தைக் கொடுக்கும். மறுபுறம், பரிமாற்றம் இப்படி இருந்தால்: ஹோல்டர் ஹோல்டர்(சில மதிப்பு); , பின்னர் PPZ நகலெடுப்பது மற்றும் நகர்த்துவது ஆகிய இரண்டையும் செய்யும் என்பதன் காரணமாக நிச்சயமாக இழக்கிறது, அதேசமயம் PPSC உடனான பதிப்பில் ஒரே ஒரு நகல் மட்டுமே இருக்கும். அந்த. PPZ, நாம் முற்றிலும் செயல்திறனைக் கருத்தில் கொண்டால், குறியீட்டின் அளவு மற்றும் "முழு" (&& ) இயக்கத்தின் சொற்பொருளுக்கான ஆதரவு ஆகியவற்றிற்கு இடையே ஒருவித சமரசம் என்று மாறிவிடும்.

அதனால்தான் ஸ்காட் தனது அறிவுரைகளை மிகவும் கவனமாகச் சொல்லி, அதை மிகவும் கவனமாக விளம்பரப்படுத்துகிறார். அவர் அழுத்தத்தில் இருப்பது போல் தயக்கத்துடன் அதைக் கொண்டு வந்ததாக எனக்குத் தோன்றியது: புத்தகத்தில் இந்த தலைப்பில் விவாதங்களை வைக்காமல் இருக்க முடியவில்லை, ஏனென்றால் ... இது மிகவும் பரவலாக விவாதிக்கப்பட்டது, மேலும் ஸ்காட் எப்போதும் கூட்டு அனுபவத்தை சேகரிப்பவராக இருந்தார். கூடுதலாக, அவர் PPZ இன் பாதுகாப்பில் மிகக் குறைவான வாதங்களைத் தருகிறார், ஆனால் இந்த "தொழில்நுட்பத்தை" கேள்விக்குட்படுத்தும் பலவற்றை அவர் கொடுக்கிறார். பிபிபியைப் பாதுகாப்பதில் ஸ்காட் முன்வைக்கும் வாதத்தை (மனதளவில் சேர்ப்பது) சுருக்கமாக இங்கே கூறுவோம். "பொருள் இயக்கத்தை ஆதரிக்கிறது மற்றும் அது மலிவானது"): rvalue வெளிப்பாட்டை செயல்பாடு வாதமாக அனுப்பும்போது நகலெடுப்பதைத் தவிர்க்க உங்களை அனுமதிக்கிறது. ஆனால் மேயர்ஸின் புத்தகத்தை வேதனைப்படுத்துவது போதுமானது, மற்றொரு புத்தகத்திற்கு செல்லலாம்.

சொல்லப்போனால், யாராவது புத்தகத்தைப் படித்துவிட்டு, மேயர்களால் உலகளாவிய குறிப்புகள் என்று அழைக்கப்படும் ஒரு விருப்பத்தை நான் இங்கே சேர்க்கவில்லை என்று ஆச்சரியப்பட்டால் - இப்போது முன்னனுப்புதல் குறிப்புகள் என்று அறியப்படுகிறது - இது எளிதாக விளக்கப்படுகிறது. நான் PPZ மற்றும் PPSC ஐ மட்டுமே கருத்தில் கொண்டுள்ளேன், ஏனெனில்... இரண்டு வகையான (rvalue/lvalue) குறிப்பு மூலம் கடந்து செல்வதை ஆதரிப்பதற்காக வார்ப்புருக்கள் இல்லாத முறைகளுக்கு டெம்ப்ளேட் செயல்பாடுகளை அறிமுகப்படுத்துவது மோசமான வடிவமாக நான் கருதுகிறேன். குறியீடு வேறுபட்டது (இனி நிலைத்தன்மை இல்லை) மற்றும் அதனுடன் பிற சிக்கல்களைக் கொண்டுவருகிறது என்ற உண்மையை குறிப்பிட தேவையில்லை.

ஜோசட்டிஸ் மற்றும் நிறுவனம்

நாம் பார்க்கப்போகும் கடைசிப் புத்தகம் “C++ டெம்ப்ளேட்கள்” ஆகும், இது இந்தக் கட்டுரையில் குறிப்பிடப்பட்டுள்ள அனைத்து புத்தகங்களிலும் மிகச் சமீபத்தியது. இது 2017 இன் இறுதியில் வெளியிடப்பட்டது (மற்றும் 2018 புத்தகத்தில் சுட்டிக்காட்டப்பட்டுள்ளது). மற்ற புத்தகங்களைப் போலல்லாமல், இது முற்றிலும் வடிவங்களுக்கு அர்ப்பணிக்கப்பட்டுள்ளது, மேலும் ஆலோசனை (மேயர்ஸ் போன்றவை) அல்லது பொதுவாக சி++, ஸ்ட்ரோஸ்ட்ரப் போன்றது அல்ல. எனவே, வார்ப்புருக்கள் எழுதும் பார்வையில் இருந்து சாதக/தீமைகள் இங்கே கருதப்படுகின்றன.

முழு அத்தியாயம் 7 இந்த தலைப்புக்கு அர்ப்பணிக்கப்பட்டுள்ளது, இது "மதிப்பால் அல்லது குறிப்பு மூலம்?" என்ற சொற்பொழிவு தலைப்பைக் கொண்டுள்ளது. இந்த அத்தியாயத்தில், ஆசிரியர்கள் மிகவும் சுருக்கமாக ஆனால் சுருக்கமாக அனைத்து பரிமாற்ற முறைகளையும் அவற்றின் அனைத்து நன்மை தீமைகளுடன் விவரிக்கிறார்கள். செயல்திறனின் பகுப்பாய்வு நடைமுறையில் இங்கே கொடுக்கப்படவில்லை, மேலும் PPSC PPZ ஐ விட வேகமாக இருக்கும் என்பது சாதாரணமாக எடுத்துக் கொள்ளப்படுகிறது. ஆனால் இவை அனைத்தையும் கொண்டு, அத்தியாயத்தின் முடிவில், டெம்ப்ளேட் செயல்பாடுகளுக்கு இயல்புநிலை PPP ஐப் பயன்படுத்த ஆசிரியர்கள் பரிந்துரைக்கின்றனர். ஏன்? ஒரு இணைப்பைப் பயன்படுத்துவதால், டெம்ப்ளேட் அளவுருக்கள் முழுமையாகக் காட்டப்படும், மேலும் இணைப்பு இல்லாமல் அவை "சிதைந்து" உள்ளன, இது வரிசைகள் மற்றும் சரம் எழுத்துகளின் செயலாக்கத்தில் நன்மை பயக்கும். சில வகையான PPP க்கு அது பயனற்றதாக மாறினால், நீங்கள் எப்போதும் std::ref மற்றும் std::cref ஐப் பயன்படுத்தலாம் என்று ஆசிரியர்கள் நம்புகின்றனர். இது சில ஆலோசனைகள், நேர்மையாக இருக்க, மேலே உள்ள செயல்பாடுகளைப் பயன்படுத்த விரும்பும் பலரை நீங்கள் பார்த்திருக்கிறீர்களா?

PPSC பற்றி அவர்கள் என்ன ஆலோசனை கூறுகிறார்கள்? செயல்திறன் முக்கியமானதாக இருக்கும் போது அல்லது மற்றவை இருக்கும்போது PPSC ஐப் பயன்படுத்துமாறு அவர்கள் அறிவுறுத்துகிறார்கள் கனமான PPP ஐ பயன்படுத்தாததற்கான காரணங்கள். நிச்சயமாக, நாங்கள் இங்கே கொதிகலன் குறியீட்டைப் பற்றி மட்டுமே பேசுகிறோம், ஆனால் இந்த அறிவுரை ஒரு தசாப்தமாக புரோகிராமர்கள் கற்பிக்கப்பட்ட அனைத்தையும் நேரடியாக முரண்படுகிறது. இது பிபிபியை மாற்றாகக் கருதுவதற்கான அறிவுரை மட்டுமல்ல - இல்லை, இது பிபிஎஸ்சியை மாற்றாக மாற்றுவதற்கான ஆலோசனை.

இது எங்கள் புத்தகப் பயணத்தை முடிக்கிறது, ஏனென்றால்... இந்தப் பிரச்சினையில் நாம் கலந்தாலோசிக்க வேண்டிய வேறு எந்தப் புத்தகங்களும் எனக்குத் தெரியாது. வேறொரு ஊடக வெளிக்கு செல்லலாம்.

நெட்வொர்க் ஞானம்

ஏனெனில் நாம் இணைய யுகத்தில் வாழ்கிறோம், பிறகு புத்தக ஞானத்தை மட்டும் நம்பி இருக்கக் கூடாது. மேலும், புத்தகங்கள் எழுதி வந்த பல எழுத்தாளர்கள் இப்போது வலைப்பதிவுகளை எழுதிவிட்டு புத்தகங்களை கைவிட்டுவிட்டனர். இந்த ஆசிரியர்களில் ஒருவர் ஹெர்ப் சட்டர் ஆவார், அவர் மே 2013 இல் தனது வலைப்பதிவில் “GotW #4 தீர்வு: வகுப்பு இயக்கவியல்” ஒரு கட்டுரையை வெளியிட்டார், இது நாங்கள் உள்ளடக்கிய சிக்கலுக்கு முழுமையாக அர்ப்பணிக்கவில்லை என்றாலும், அதை இன்னும் தொடுகிறது.

எனவே, கட்டுரையின் அசல் பதிப்பில், சுட்டர் பழைய ஞானத்தை மீண்டும் மீண்டும் கூறினார்: "ஒரு மாறிலியைக் குறிப்பதன் மூலம் அளவுருக்களை அனுப்பவும்", ஆனால் கட்டுரையின் இந்த பதிப்பை நாங்கள் இனி பார்க்க மாட்டோம், ஏனெனில் கட்டுரையில் எதிர் ஆலோசனை உள்ளது: " என்றால்அளவுரு இன்னும் நகலெடுக்கப்படும், பின்னர் அதை மதிப்பின் மூலம் அனுப்பவும்." மீண்டும் மோசமான "என்றால்". சுட்டர் ஏன் கட்டுரையை மாற்றினார், அதைப் பற்றி எனக்கு எப்படித் தெரியும்? கருத்துகளில் இருந்து. அவரது கட்டுரைக்கான கருத்துகளைப் படியுங்கள், அவை கட்டுரையை விட மிகவும் சுவாரஸ்யமானவை மற்றும் பயனுள்ளவை. உண்மை, கட்டுரையை எழுதிய பிறகு, சுட்டர் இறுதியாக தனது கருத்தை மாற்றிக்கொண்டார், மேலும் அவர் இனி அத்தகைய ஆலோசனையை வழங்கவில்லை. 2014 இல் CppCon இல் அவர் ஆற்றிய உரையில் கருத்து மாற்றத்தைக் காணலாம்: “அடிப்படைகளுக்குத் திரும்பு! எசென்ஷியல்ஸ் ஆஃப் மாடர்ன் சி++ ஸ்டைல்". பார்க்கவும், அடுத்த இணைய இணைப்பிற்கு செல்வோம்.

அடுத்ததாக 21 ஆம் நூற்றாண்டின் முக்கிய நிரலாக்க ஆதாரம் எங்களிடம் உள்ளது: StackOverflow. அல்லது பதில், இந்தக் கட்டுரையை எழுதும் போது நேர்மறை எதிர்வினைகளின் எண்ணிக்கை 1700ஐத் தாண்டியது. கேள்வி: நகல் மற்றும் இடமாற்று மொழி என்றால் என்ன? , மற்றும், தலைப்பு குறிப்பிடுவது போல, நாங்கள் பார்க்கும் தலைப்பில் இல்லை. ஆனால் இந்தக் கேள்விக்கான பதிலில், ஆசிரியர் நமக்கு ஆர்வமுள்ள ஒரு தலைப்பையும் தொடுகிறார். "எப்படியும் வாதம் நகலெடுக்கப்பட்டால்" PPZ ஐப் பயன்படுத்தவும் அவர் அறிவுறுத்துகிறார் (கடவுளால் இதற்கும் ஒரு சுருக்கத்தை அறிமுகப்படுத்த வேண்டிய நேரம் இது). பொதுவாக, இந்த ஆலோசனையானது அவரது பதில் மற்றும் ஆபரேட்டர்= அங்கு விவாதிக்கப்பட்ட கட்டமைப்பிற்குள் மிகவும் பொருத்தமானதாகத் தோன்றுகிறது, ஆனால் இந்த குறிப்பிட்ட விஷயத்தில் மட்டுமல்ல, பரந்த முறையில் அத்தகைய ஆலோசனையை வழங்க ஆசிரியர் சுதந்திரம் பெறுகிறார். மேலும், நாம் முன்பு விவாதித்த அனைத்து உதவிக்குறிப்புகளையும் விட அவர் மேலும் செல்கிறார் மற்றும் C++03 குறியீட்டிலும் இதைச் செய்ய அழைப்பு விடுக்கிறார்! அத்தகைய முடிவுகளை எடுக்க ஆசிரியரைத் தூண்டியது எது?

வெளிப்படையாக, பதில் ஆசிரியர் மற்றொரு புத்தக ஆசிரியர் மற்றும் Boost.MPL இன் பகுதிநேர டெவலப்பர் - டேவ் ஆபிரகாம்ஸின் கட்டுரையிலிருந்து முக்கிய உத்வேகத்தைப் பெற்றார். கட்டுரையின் பெயர் “வேகம் வேண்டுமா? பாஸ் பை வேல்யூ” , மற்றும் இது ஆகஸ்ட் 2009 இல் மீண்டும் வெளியிடப்பட்டது, அதாவது. C++11 மற்றும் நகர்வு சொற்பொருள் அறிமுகப்படுத்தப்படுவதற்கு 2 ஆண்டுகளுக்கு முன்பு. முந்தைய நிகழ்வுகளைப் போலவே, வாசகர் சொந்தமாக கட்டுரையைப் படிக்க பரிந்துரைக்கிறேன், ஆனால் PPZ க்கு ஆதரவாக டேவ் கொடுக்கும் முக்கிய வாதங்களை (உண்மையில், ஒரே ஒரு வாதம் உள்ளது) தருகிறேன்: நீங்கள் PPZ ஐப் பயன்படுத்த வேண்டும். , ஏனெனில் "நகலைத் தவிர்" தேர்வுமுறை அதனுடன் நன்றாக வேலை செய்கிறது ( நகல் எலிஷன்), இது PPSC இல் இல்லை. கட்டுரைக்கான கருத்துகளை நீங்கள் படித்தால், அவர் ஊக்குவிக்கும் அறிவுரை உலகளாவியது அல்ல என்பதை நீங்கள் காணலாம், வர்ணனையாளர்களின் விமர்சனங்களுக்கு பதிலளிக்கும் போது ஆசிரியரே அதை உறுதிப்படுத்துகிறார். இருப்பினும், வாதம் எப்படியும் நகலெடுக்கப்பட்டால், PPP ஐப் பயன்படுத்துவதற்கான வெளிப்படையான ஆலோசனை (வழிகாட்டி) கட்டுரையில் உள்ளது. மூலம், யாராவது ஆர்வமாக இருந்தால், நீங்கள் கட்டுரையைப் படிக்கலாம் “வேகம் வேண்டுமா? (எப்போதும்) மதிப்பைக் கடந்து செல்ல வேண்டாம். . தலைப்பு குறிப்பிடுவது போல, இந்த கட்டுரை டேவின் கட்டுரைக்கான பதில், எனவே நீங்கள் முதல் கட்டுரையைப் படித்தால், இதையும் படிக்க மறக்காதீர்கள்!

துரதிர்ஷ்டவசமாக (சிலருக்கு அதிர்ஷ்டவசமாக), பிரபலமான தளங்களில் இதுபோன்ற கட்டுரைகள் மற்றும் (இன்னும் அதிகமாக) பிரபலமான பதில்கள் சந்தேகத்திற்குரிய நுட்பங்களை (ஒரு அற்பமான உதாரணம்) பெருமளவில் பயன்படுத்துவதற்கு வழிவகுத்தது, ஏனெனில் இதற்கு குறைவான எழுத்து தேவைப்படுகிறது, மேலும் பழைய கோட்பாடு இனி அசைக்க முடியாதது - நீங்கள் சுவரில் தள்ளப்பட்டால் "அந்த பிரபலமான ஆலோசனையை" நீங்கள் எப்போதும் குறிப்பிடலாம். குறியீட்டை எழுதுவதற்கான பரிந்துரைகளுடன் பல்வேறு ஆதாரங்கள் எங்களுக்கு என்ன வழங்குகின்றன என்பதை நீங்கள் அறிந்துகொள்ள இப்போது நான் பரிந்துரைக்கிறேன்.

ஏனெனில் பல்வேறு தரநிலைகள் மற்றும் பரிந்துரைகள் இப்போது ஆன்லைனில் வெளியிடப்பட்டுள்ளதால், இந்தப் பகுதியை "நெட்வொர்க் விஸ்டம்" என்று வகைப்படுத்த முடிவு செய்தேன். எனவே, இங்கே நான் இரண்டு ஆதாரங்களைப் பற்றி பேச விரும்புகிறேன், இதன் நோக்கம் C++ புரோகிராமர்களின் குறியீட்டை சிறந்ததாக்குவது, இந்த குறியீட்டை எவ்வாறு எழுதுவது என்பதற்கான உதவிக்குறிப்புகளை (வழிகாட்டுதல்கள்) அவர்களுக்கு வழங்குவதாகும்.

நான் கருத்தில் கொள்ள விரும்பும் முதல் விதிகள் இந்த கட்டுரையை எடுக்க என்னை கட்டாயப்படுத்திய கடைசி வைக்கோல் ஆகும். இந்த செட் கிளாங்-டிடி பயன்பாட்டின் ஒரு பகுதியாகும் மற்றும் அதற்கு வெளியே இல்லை. கணகண வென்ற சப்தம் தொடர்பான அனைத்தையும் போலவே, இந்த பயன்பாடு மிகவும் பிரபலமானது மற்றும் ஏற்கனவே CLion மற்றும் Resharper C++ உடன் ஒருங்கிணைப்பைப் பெற்றுள்ளது (அப்படித்தான் நான் அதைக் கண்டேன்). எனவே, clang-tydy ஆனது PPSC வழியாக வாதங்களை ஏற்றுக்கொள்ளும் கட்டமைப்பாளர்களில் வேலை செய்யும் நவீனமயமாக்கல்-பாஸ்-பை-மதிப்பு விதியைக் கொண்டுள்ளது. இந்த விதி PPSC ஐ PPZ உடன் மாற்றுமாறு அறிவுறுத்துகிறது. மேலும், கட்டுரை எழுதும் நேரத்தில், இந்த விதியின் விளக்கத்தில் இந்த விதி என்று ஒரு குறிப்பு உள்ளது வருகிறேன்கட்டமைப்பாளர்களுக்கு மட்டுமே வேலை செய்கிறது, ஆனால் அவர்கள் (அவர்கள் யார்?) இந்த விதியை மற்ற நிறுவனங்களுக்கு நீட்டிப்பவர்களிடமிருந்து உதவியை மகிழ்ச்சியுடன் ஏற்றுக்கொள்வார்கள். அங்கு, விளக்கத்தில், டேவின் கட்டுரைக்கான இணைப்பும் உள்ளது - கால்கள் எங்கிருந்து வருகின்றன என்பது தெளிவாகிறது.

இறுதியாக, மற்றவர்களின் ஞானம் மற்றும் அதிகாரபூர்வமான கருத்துகளின் இந்த மதிப்பாய்வை முடிக்க, C++ குறியீட்டை எழுதுவதற்கான அதிகாரப்பூர்வ வழிகாட்டுதல்களைப் பார்க்க பரிந்துரைக்கிறேன்: C++ கோர் வழிகாட்டுதல்கள், ஹெர்ப் சட்டர் மற்றும் Bjarne Stroustrup (மோசமாக இல்லை, சரியா?) முக்கிய எடிட்டர்கள். எனவே, இந்த பரிந்துரைகள் பின்வரும் விதியைக் கொண்டிருக்கின்றன: “இன்” அளவுருக்களுக்கு, மலிவாக நகலெடுக்கப்பட்ட வகைகளை மதிப்பின் மூலமும் மற்றவை கான்ஸ்டைக் குறிப்பதன் மூலமும் அனுப்பவும், இது பழைய ஞானத்தை முழுவதுமாக மீண்டும் செய்கிறது: எல்லா இடங்களிலும் பிபிஎஸ்கே மற்றும் சிறிய பொருட்களுக்கு பிபிபி. இந்த உதவிக்குறிப்பு கருத்தில் கொள்ள பல மாற்று வழிகளை கோடிட்டுக் காட்டுகிறது. வாதத்திற்கு உகந்ததாக இருந்தால். ஆனால் PPZ மாற்று பட்டியலில் சேர்க்கப்படவில்லை!

கவனத்திற்குத் தகுதியான வேறு ஆதாரங்கள் என்னிடம் இல்லாததால், பரிமாற்றத்தின் இரண்டு முறைகளின் நேரடி பகுப்பாய்விற்குச் செல்ல நான் முன்மொழிகிறேன்.

பகுப்பாய்வு

முந்தைய உரை முழுவதும் எனக்கு சற்று அசாதாரணமான முறையில் எழுதப்பட்டுள்ளது: நான் மற்றவர்களின் கருத்துக்களை முன்வைக்கிறேன், மேலும் எனது சொந்த கருத்தை வெளிப்படுத்தாமல் இருக்க முயற்சிக்கிறேன் (அது மோசமாக மாறும் என்று எனக்குத் தெரியும்). மற்றவர்களின் கருத்துக்கள் மற்றும் அவற்றைப் பற்றிய சுருக்கமான கண்ணோட்டத்தை உருவாக்குவதே எனது குறிக்கோளாக இருந்ததால், மற்ற ஆசிரியர்களிடம் நான் கண்ட சில வாதங்களின் விரிவான பரிசீலனையை நான் ஒத்திவைத்தேன். இந்த பிரிவில், நான் அதிகாரிகளைக் குறிப்பிடமாட்டேன் மற்றும் கருத்துகளை வழங்கமாட்டேன், PPSC மற்றும் PPZ இன் சில புறநிலை நன்மைகள் மற்றும் தீமைகள் பற்றி இங்கு பார்ப்போம், இது எனது அகநிலை கருத்துடன் சுவைக்கப்படும். நிச்சயமாக, முன்பு விவாதிக்கப்பட்டவை சில மீண்டும் மீண்டும் செய்யப்படும், ஆனால், இந்த கட்டுரையின் அமைப்பு இதுதான்.

PPP க்கு நன்மை உள்ளதா?

எனவே, ஆதரவாகவும் எதிராகவும் உள்ள வாதங்களைக் கருத்தில் கொள்வதற்கு முன், மதிப்பைக் கடந்து செல்வது நமக்கு என்ன நன்மைகளைத் தருகிறது என்பதைப் பார்க்க நான் முன்மொழிகிறேன். எங்களிடம் இது போன்ற ஒரு வகுப்பு உள்ளது என்று வைத்துக்கொள்வோம்:

Class CopyMover (பொது: void setByValuer (Accounter byValuer) (m_ByValuer = std::move(byValuer); ) செல்லாது setByRefer(const Accounter& byRefer) (m_ByRefer = byRefer; ) void setByValuer_Andal yValuerAndNotMover = byV aluerAndNotMover வெற்றிடமான setRvaluer; (கணக்கு&& rvaluer) ( m_Rvaluer = std ::move(rvaluer); ) );

இந்த கட்டுரையின் நோக்கங்களுக்காக நாங்கள் முதல் இரண்டு செயல்பாடுகளில் மட்டுமே ஆர்வமாக உள்ளோம், மாறாக அவற்றைப் பயன்படுத்த நான்கு விருப்பங்களைச் சேர்த்துள்ளேன்.

கணக்காளர் வகுப்பு என்பது எத்தனை முறை நகலெடுக்கப்பட்டது/நகர்த்தப்பட்டது என்பதைக் கணக்கிடும் எளிய வகுப்பாகும். CopyMover வகுப்பில் பின்வரும் விருப்பங்களைக் கருத்தில் கொள்ள அனுமதிக்கும் செயல்பாடுகளை நாங்கள் செயல்படுத்தியுள்ளோம்:

    நகரும்வாதம் நிறைவேற்றப்பட்டது.

    மதிப்பின்படி கடந்து செல்லவும், அதைத் தொடர்ந்து நகலெடுக்கிறதுவாதம் நிறைவேற்றப்பட்டது.

இப்போது, ​​இந்த செயல்பாடுகள் ஒவ்வொன்றிற்கும் ஒரு மதிப்பை அனுப்பினால், எடுத்துக்காட்டாக இது போன்றது:

Refer மூலம் கணக்காளர்; மதிப்பீட்டாளர் மூலம் கணக்காளர்; ValuerAndNotMover மூலம் கணக்காளர்; காப்பி மூவர் காப்பி மூவர்; copyMover.setByRefer(byRefer); copyMover.setByValuer(byValuer); copyMover.setByValuerAndNotMover(byValuerAndNotMover);

பின்னர் பின்வரும் முடிவுகளைப் பெறுகிறோம்:

வெளிப்படையான வெற்றியாளர் PPSK, ஏனெனில்... PPZ ஒரு நகலையும் ஒரு நகர்வையும் கொடுக்கிறது.

இப்போது மதிப்பீட்டைக் கடக்க முயற்சிப்போம்:

காப்பி மூவர் காப்பி மூவர்; copyMover.setByRefer(Accounter()); copyMover.setByValuer(Accounter()); copyMover.setByValuerAndNotMover(Accounter()); copyMover.setRvaluer(Accounter());

பின்வருவனவற்றைப் பெறுகிறோம்:

இங்கே தெளிவான வெற்றியாளர் இல்லை, ஏனென்றால்... PPZ மற்றும் PPSK இரண்டும் தலா ஒரு செயல்பாட்டைக் கொண்டுள்ளன, ஆனால் PPZ இயக்கத்தைப் பயன்படுத்துவதால், PPSK நகலெடுப்பதைப் பயன்படுத்துவதால், நாம் PPZ க்கு வெற்றியைக் கொடுக்க முடியும்.

ஆனால் எங்கள் சோதனைகள் அங்கு முடிவடையவில்லை, ஒரு மறைமுக அழைப்பை உருவகப்படுத்த பின்வரும் செயல்பாடுகளைச் சேர்ப்போம் (அடுத்தடுத்த வாதத்துடன்):

செல்லாது setByValuer(Accounter byValuer, CopyMover& copyMover) ( copyMover.setByValuer(std::move(byValuer)); ) void setByRefer(const Accounter& byRefer, CopyMover& copyMover) ( copyMover.setByRefer)

அவை இல்லாமல் நாங்கள் செய்ததைப் போலவே அவற்றைப் பயன்படுத்துவோம், எனவே நான் குறியீட்டை மீண்டும் செய்ய மாட்டேன் (தேவைப்பட்டால் களஞ்சியத்தில் பாருங்கள்). எனவே, மதிப்பிற்கு, முடிவுகள் இப்படி இருக்கும்:

PPZ ஆனது PPZ உடனான இடைவெளியை அதிகரிக்கிறது என்பதை நினைவில் கொள்ளவும், அதே நேரத்தில் PPZ க்கு ஏற்கனவே 3 செயல்பாடுகள் உள்ளன (மேலும் ஒரு இயக்கம்)!

இப்போது நாம் மதிப்பைக் கடந்து பின்வரும் முடிவுகளைப் பெறுகிறோம்:

இப்போது PPZ க்கு 2 இயக்கங்கள் உள்ளன, மேலும் PPSC இல் இன்னும் ஒரு நகல் உள்ளது. இப்போது PPZ ஐ வெற்றியாளராக பரிந்துரைக்க முடியுமா? இல்லை, ஏனெனில் ஒரு நகர்வு குறைந்தது ஒரு பிரதியை விட மோசமாக இருக்க வேண்டும் என்றால், 2 நகர்வுகளைப் பற்றி நாம் சொல்ல முடியாது. எனவே, இந்த எடுத்துக்காட்டில் வெற்றியாளர் யாரும் இருக்க மாட்டார்கள்.

அவர்கள் என்னை எதிர்க்கலாம்: “ஆசிரியரே, நீங்கள் ஒரு பக்கச்சார்பான கருத்தைக் கொண்டிருக்கிறீர்கள், மேலும் உங்களுக்கு நன்மை பயக்கும் விஷயங்களில் நீங்கள் இழுக்கிறீர்கள். நகலெடுப்பதை விட 2 நகர்வுகள் கூட மலிவானதாக இருக்கும்! இந்த அறிக்கையுடன் என்னால் உடன்பட முடியாது மொத்தத்தில், ஏனெனில் நகலெடுப்பதை விட எவ்வளவு வேகமாக நகரும் என்பது குறிப்பிட்ட வகுப்பைப் பொறுத்தது, ஆனால் "மலிவான" நகர்வை ஒரு தனிப் பிரிவில் பார்ப்போம்.

இங்கே நாம் ஒரு சுவாரஸ்யமான விஷயத்தைத் தொட்டோம்: நாங்கள் ஒரு மறைமுக அழைப்பைச் சேர்த்துள்ளோம், மேலும் PPP "எடையில்" சரியாக ஒரு செயல்பாட்டைச் சேர்த்தது. எங்களிடம் அதிக மறைமுக அழைப்புகள் இருந்தால், PPZ ஐப் பயன்படுத்தும் போது அதிக செயல்பாடுகள் செய்யப்படும், அதே நேரத்தில் PPSC க்கு எண் மாறாமல் இருக்கும் என்பதை புரிந்து கொள்ள MSTU இலிருந்து நீங்கள் டிப்ளோமா பெற்றிருக்க வேண்டியதில்லை என்று நினைக்கிறேன்.

மேலே விவாதிக்கப்பட்ட அனைத்தும் யாருக்கும் வெளிப்பாடாக இருக்க வாய்ப்பில்லை, நாங்கள் சோதனைகள் கூட செய்திருக்க மாட்டோம் - இந்த எண்கள் அனைத்தும் முதல் பார்வையில் பெரும்பாலான சி++ புரோகிராமர்களுக்கு தெளிவாக இருக்க வேண்டும். உண்மை, ஒரு புள்ளி இன்னும் தெளிவுபடுத்தப்பட வேண்டும்: ஏன், மதிப்பின் விஷயத்தில், PZ இல் ஒரு நகல் (அல்லது மற்றொரு நகர்வு) இல்லை, ஆனால் ஒரே ஒரு நகர்வு.

சரி, நகல்களின் எண்ணிக்கை மற்றும் நகர்வுகளின் எண்ணிக்கையை நேரடியாகக் கவனிப்பதன் மூலம் PPZ மற்றும் PPSC இடையே பரிமாற்றத்தில் உள்ள வேறுபாட்டைப் பார்த்தோம். PPSC ஐ விட PPZ இன் நன்மை என்னவென்றால், இதுபோன்ற எளிய எடுத்துக்காட்டுகளில் கூட அதை லேசாகச் சொல்வதுதான். இல்லைவெளிப்படையாக, நான் இன்னும், கொஞ்சம் பாசாங்குத்தனமாக, பின்வரும் முடிவை எடுக்கிறேன்: நாம் இன்னும் செயல்பாடு வாதத்தை நகலெடுக்கப் போகிறோம் என்றால், மதிப்பின்படி செயல்பாட்டிற்கு வாதத்தை அனுப்புவது கருத்தில் கொள்வது அர்த்தமுள்ளதாக இருக்கிறது. நான் ஏன் இந்த முடிவை எடுத்தேன்? சுமூகமாக அடுத்த பகுதிக்குச் செல்ல.

நாம் நகலெடுத்தால்...

எனவே, "என்றால்" என்ற பழமொழிக்கு வருகிறோம். நாங்கள் எதிர்கொண்ட பெரும்பாலான வாதங்கள் PPSC க்கு பதிலாக PPP ஐ உலகளாவிய முறையில் செயல்படுத்துவதற்கு அழைப்பு விடுக்கவில்லை. இந்த வாதத்தில் என்ன தவறு என்று கண்டுபிடிக்க வேண்டிய நேரம் இது.

நான் எப்படி குறியீட்டை எழுதுகிறேன் என்பதற்கான சிறிய விளக்கத்துடன் தொடங்க விரும்புகிறேன். சமீபத்தில், எனது குறியீட்டு செயல்முறை TDD போன்றது, அதாவது. எந்த வகுப்பு முறையை எழுதுவதும் இந்த முறை தோன்றும் ஒரு தேர்வை எழுதுவதில் தொடங்குகிறது. அதன்படி, தேர்வு எழுதத் தொடங்கும் போதும், தேர்வு எழுதிய பிறகு ஒரு முறையை உருவாக்கும்போதும், நான் வாதத்தை நகலெடுப்பேனா என்று எனக்குத் தெரியவில்லை. நிச்சயமாக, அனைத்து செயல்பாடுகளும் இந்த வழியில் உருவாக்கப்படவில்லை, ஒரு சோதனை எழுதும் செயல்பாட்டில் கூட, எந்த வகையான செயல்படுத்தல் இருக்கும் என்பது உங்களுக்குத் தெரியும். ஆனால் இது எப்போதும் நடக்காது!

இந்த முறை முதலில் எப்படி எழுதப்பட்டது என்பது முக்கியமில்லை, அந்த முறை வடிவம் பெற்றவுடன், வாதத்தை எவ்வாறு கடந்து செல்கிறோம் என்பதை மாற்றலாம், மேலும் அங்கு என்ன நடக்கிறது என்பது எங்களுக்கு முற்றிலும் தெளிவாகத் தெரியும் (அதாவது நகலெடுக்கிறதா அல்லது இல்லை). நான் இதை ஓரளவு ஒப்புக்கொள்கிறேன் - உண்மையில், நீங்கள் இதை இப்படி செய்யலாம், ஆனால் இது ஒருவித விசித்திரமான விளையாட்டில் நம்மை ஈடுபடுத்துகிறது, அங்கு செயல்படுத்தல் மாறியதால் இடைமுகங்களை மாற்ற வேண்டும். இது நம்மை அடுத்த இக்கட்டான நிலைக்கு கொண்டு செல்கிறது.

அது எவ்வாறு செயல்படுத்தப்படும் என்பதன் அடிப்படையில் இடைமுகத்தை மாற்றியமைக்கிறோம் (அல்லது திட்டமிடுகிறோம்). OOP மற்றும் மென்பொருள் கட்டமைப்பின் பிற கோட்பாட்டு கணக்கீடுகளில் நான் ஒரு நிபுணராக கருதவில்லை, ஆனால் அத்தகைய செயல்கள் அடிப்படை விதிகளை தெளிவாக முரண்படுகின்றன. நிச்சயமாக, சில செயல்படுத்தல் விவரங்கள் (அவை மொழியின் அம்சங்களாக இருந்தாலும் அல்லது இலக்கு இயங்குதளமாக இருந்தாலும்) இன்னும் ஒரு வழி அல்லது வேறு இடைமுகத்தின் மூலம் கசியும், ஆனால் நீங்கள் அத்தகைய விஷயங்களின் எண்ணிக்கையைக் குறைக்க முயற்சிக்க வேண்டும், அதிகரிக்க வேண்டாம்.

சரி, கடவுள் அவரை ஆசீர்வதிப்பார், இந்த பாதையில் செல்லலாம், வாதத்தை நகலெடுப்பதில் நாம் என்ன செய்கிறோம் என்பதைப் பொறுத்து இடைமுகங்களை மாற்றுவோம். இந்த முறையை நாங்கள் எழுதினோம் என்று வைத்துக்கொள்வோம்:

வெற்றிடமான setName(பெயர் பெயர்) ( m_Name = நகர்த்து(பெயர்);)

மற்றும் எங்கள் மாற்றங்களை களஞ்சியத்தில் செய்தோம். காலப்போக்கில், எங்கள் மென்பொருள் தயாரிப்பு புதிய செயல்பாட்டைப் பெற்றது, புதிய கட்டமைப்புகள் ஒருங்கிணைக்கப்பட்டன, மேலும் எங்கள் வகுப்பில் ஏற்படும் மாற்றங்களைப் பற்றி வெளி உலகிற்குத் தெரிவிக்கும் பணி எழுந்தது. அந்த. எங்கள் முறையில் சில அறிவிப்பு பொறிமுறையைச் சேர்ப்போம், இது Qt சிக்னல்களைப் போலவே இருக்கட்டும்:

வெற்றிடமான setName(பெயர் பெயர்) ( m_Name = நகர்வு(பெயர்); பெயர்மாற்றம்(m_Name); )

இந்தக் குறியீட்டில் ஏதேனும் சிக்கல் உள்ளதா? சாப்பிடு. setName க்கு ஒவ்வொரு அழைப்புக்கும் நாம் ஒரு சிக்னலை அனுப்புகிறோம், எனவே சிக்னல் எப்போது அனுப்பப்படும் பொருள் m_பெயர் மாறவில்லை. செயல்திறன் சிக்கல்கள் தவிர, மேலே உள்ள அறிவிப்பைப் பெறும் குறியீடு எப்படியாவது setName ஐ அழைக்க வருவதால், இந்த நிலைமை எல்லையற்ற சுழற்சிக்கு வழிவகுக்கும். இந்த எல்லா சிக்கல்களையும் தவிர்க்க, இதுபோன்ற முறைகள் பெரும்பாலும் இதுபோன்றவை:

வெற்றிடமான setName(பெயர் பெயர்) (if(name == m_Name) திரும்பவும்; m_Name = நகர்த்து(பெயர்); பெயர்மாற்றம்(m_Name);)

மேலே விவரிக்கப்பட்ட சிக்கல்களிலிருந்து நாங்கள் விடுபட்டோம், ஆனால் இப்போது எங்கள் “எப்படியும் நகலெடுத்தால்...” விதி தோல்வியடைந்தது - வாதத்தின் நிபந்தனையற்ற நகலெடுப்பு இனி இல்லை, இப்போது அது மாறினால் மட்டுமே அதை நகலெடுக்கிறோம்! எனவே நாம் இப்போது என்ன செய்ய வேண்டும்? இடைமுகத்தை மாற்றவா? சரி, இந்த பிழைத்திருத்தத்தின் காரணமாக வகுப்பு இடைமுகத்தை மாற்றுவோம். சில சுருக்க இடைமுகத்திலிருந்து எங்கள் வகுப்பு இந்த முறையைப் பெற்றிருந்தால் என்ன செய்வது? அங்கேயும் மாற்றுவோம்! செயல்படுத்தல் மாறியதால் நிறைய மாற்றங்கள் உண்டா?

மீண்டும் அவர்கள் என்னை எதிர்க்கக்கூடும், அவர்கள் கூறுகிறார்கள், ஆசிரியர், இந்த நிலை அங்கு செயல்படும் போது நீங்கள் ஏன் போட்டிகளில் பணத்தை சேமிக்க முயற்சிக்கிறீர்கள்? ஆம், பெரும்பாலான அழைப்புகள் பொய்யாகவே இருக்கும்! இதில் நம்பிக்கை உண்டா? எங்கே? நான் போட்டிகளில் சேமிக்க முடிவு செய்தால், நாங்கள் PPZ ஐப் பயன்படுத்தினோம் என்பது துல்லியமாக அத்தகைய சேமிப்பின் விளைவாக இல்லையா? நான் செயல்திறனை ஆதரிக்கும் "கட்சி வரிசையை" தொடர்கிறேன்.

கட்டமைப்பாளர்கள்

கன்ஸ்ட்ரக்டர்களைப் பற்றி சுருக்கமாகப் பார்ப்போம், குறிப்பாக க்ளாங்-டிடியில் அவர்களுக்கென்று ஒரு சிறப்பு விதி உள்ளது, இது இன்னும் பிற முறைகள்/செயல்பாடுகளுக்கு வேலை செய்யாது. எங்களிடம் இது போன்ற ஒரு வகுப்பு உள்ளது என்று வைத்துக்கொள்வோம்:

வகுப்பு JustClass (பொது: JustClass(const string& justString): m_JustString(justString) () தனிப்பட்ட: சரம் m_JustString; );

வெளிப்படையாக, அளவுரு நகலெடுக்கப்பட்டது, மேலும் கன்ஸ்ட்ரக்டரை இதற்கு மீண்டும் எழுதுவது நல்ல யோசனையாக இருக்கும் என்று clang-tidy நமக்குத் தெரிவிக்கும்:

JustClass(string justString): m_JustString(move(justString)) ( )

மேலும், உண்மையைச் சொல்வதானால், இங்கே வாதிடுவது எனக்கு கடினம் - எல்லாவற்றிற்கும் மேலாக, நாங்கள் எப்போதும் நகலெடுக்கிறோம். மற்றும் பெரும்பாலும், நாம் ஒரு கட்டமைப்பாளரின் வழியாக எதையாவது அனுப்பும்போது, ​​அதை நகலெடுக்கிறோம். ஆனால் பெரும்பாலும் எப்போதும் என்று அர்த்தம் இல்லை. இதோ மற்றொரு உதாரணம்:

Class TimeSpan (பொது: TimeSpan(DateTime start, DateTime end) ( if(start > end) InvalidTimeSpan(); m_Start = நகர்வு(தொடக்கம்); m_End = நகர்வு(முடிவு); ) தனிப்பட்ட: DateTime m_Start; DateTime m_End; );

இங்கே நாம் எப்போதும் நகலெடுப்பதில்லை, ஆனால் தேதிகள் சரியாக வழங்கப்பட்டால் மட்டுமே. நிச்சயமாக, பெரும்பாலான சந்தர்ப்பங்களில் இதுவே இருக்கும். ஆனாலும் எப்பொழுதும் இல்லை.

நீங்கள் மற்றொரு உதாரணம் கொடுக்கலாம், ஆனால் இந்த முறை குறியீடு இல்லாமல். ஒரு பெரிய பொருளை ஏற்றுக்கொள்ளும் வகுப்பு உங்களிடம் இருப்பதாக கற்பனை செய்து பாருங்கள். வகுப்பு நீண்ட காலமாக உள்ளது, இப்போது அதன் செயல்பாட்டைப் புதுப்பிக்க வேண்டிய நேரம் இது. ஒரு பெரிய வசதியில் பாதிக்கு மேல் நமக்குத் தேவையில்லை என்பதை நாங்கள் உணர்கிறோம் (இது பல ஆண்டுகளாக வளர்ந்துள்ளது), மேலும் குறைவாகவும் இருக்கலாம். மதிப்பைக் கடந்து இதைப் பற்றி ஏதாவது செய்ய முடியுமா? இல்லை, எங்களால் எதுவும் செய்ய முடியாது, ஏனெனில் நகல் இன்னும் உருவாக்கப்படும். ஆனால் நாங்கள் பிபிஎஸ்சியைப் பயன்படுத்தினால், நாங்கள் செய்வதை மாற்றுவோம் உள்ளேவடிவமைப்பாளர். இது முக்கிய விஷயம்: PPSC ஐப் பயன்படுத்தி, எங்கள் செயல்பாட்டை (கட்டமைப்பாளர்) செயல்படுத்துவதில் என்ன, எப்போது நடக்கிறது என்பதைக் கட்டுப்படுத்துகிறோம், ஆனால் நாம் PPZ ஐப் பயன்படுத்தினால், நகலெடுப்பதில் எந்தக் கட்டுப்பாட்டையும் இழக்கிறோம்.

இந்த பிரிவில் இருந்து என்ன எடுக்க முடியும்? "நாம் எப்படியும் நகலெடுத்தால்..." என்ற வாதம் மிகவும் சர்ச்சைக்குரியது, ஏனெனில் நாங்கள் எதை நகலெடுப்போம் என்பது எங்களுக்கு எப்போதும் தெரியாது, மேலும் நமக்குத் தெரிந்தாலும் கூட, இது எதிர்காலத்தில் தொடரும் என்பதில் எங்களுக்கு உறுதியாகத் தெரியவில்லை.

நகர்த்துவது மலிவானது

இயக்கத்தின் சொற்பொருள் தோன்றிய தருணத்திலிருந்தே, நவீன சி ++ குறியீடு எழுதப்பட்ட விதத்தில் அது தீவிரமான தாக்கத்தை ஏற்படுத்தத் தொடங்கியது, மேலும் காலப்போக்கில் இந்த செல்வாக்கு தீவிரமடைந்தது: இது ஆச்சரியமல்ல, ஏனென்றால் இயக்கம் அவ்வாறு உள்ளது. மலிவானநகலெடுப்பதை ஒப்பிடும்போது. ஆனால் அது? இயக்கம் என்பது உண்மையா எப்போதும்மலிவான அறுவை சிகிச்சை? இதைத்தான் இந்த பிரிவில் கண்டுபிடிக்க முயற்சிப்போம்.

பைனரி பெரிய பொருள்

ஒரு அற்பமான உதாரணத்துடன் ஆரம்பிக்கலாம், எங்களிடம் பின்வரும் வகுப்பு உள்ளது என்று வைத்துக்கொள்வோம்:

ஸ்ட்ரக்ட் ப்ளாப் (std::array தகவல்கள்; );

சாதாரண பொட்டு(BDO, ஆங்கிலம் BLOB), இது பல்வேறு சூழ்நிலைகளில் பயன்படுத்தப்படலாம். குறிப்பு மற்றும் மதிப்பு மூலம் கடந்து செல்வதற்கு என்ன செலவாகும் என்பதைப் பார்ப்போம். எங்கள் BDO இது போன்ற ஒன்றைப் பயன்படுத்துகிறது:

வெற்றிட சேமிப்பு::setBlobByRef(const Blob& blob) (m_Blob = blob; ) void Storage::setBlobByVal(Blob blob) (m_Blob = move(blob); )

இந்த செயல்பாடுகளை இப்படி அழைப்போம்:

கான்ஸ்ட் ப்ளாப் ப்ளாப்(); சேமிப்பு சேமிப்பு; store.setBlobByRef(blob); store.setBlobByVal(blob);

மற்ற எடுத்துக்காட்டுகளுக்கான குறியீடு இதற்கு ஒரே மாதிரியாக இருக்கும், வெவ்வேறு பெயர்கள் மற்றும் வகைகளுடன் மட்டுமே இருக்கும், எனவே மீதமுள்ள எடுத்துக்காட்டுகளுக்கு நான் அதைக் கொடுக்க மாட்டேன் - எல்லாம் களஞ்சியத்தில் உள்ளது.

அளவீடுகளுக்குச் செல்வதற்கு முன், முடிவைக் கணிக்க முயற்சிப்போம். எனவே எங்களிடம் 4 KB std::array உள்ளது, அதை சேமிப்பக வகுப்பு பொருளில் சேமிக்க வேண்டும். நாங்கள் முன்பே கண்டுபிடித்தது போல், PPSC க்கு ஒரு நகல் இருக்கும், PPZ க்கு எங்களிடம் ஒரு நகல் மற்றும் ஒரு நகர்வு இருக்கும். வரிசையை நகர்த்துவது சாத்தியமில்லை என்ற உண்மையின் அடிப்படையில், PPZக்கு 2 நகல்களும், PPSCக்கு ஒன்றும் இருக்கும். அந்த. PPSC க்கு செயல்திறனில் இரு மடங்கு மேன்மையை எதிர்பார்க்கலாம்.

இப்போது சோதனை முடிவுகளைப் பார்ப்போம்:

இதுவும் அடுத்தடுத்த அனைத்து சோதனைகளும் MSVS 2017 (15.7.2) மற்றும் /O2 கொடியைப் பயன்படுத்தி ஒரே கணினியில் இயக்கப்பட்டன.

பயிற்சி அனுமானத்துடன் ஒத்துப்போகிறது - மதிப்பைக் கடந்து செல்வது 2 மடங்கு அதிக விலை கொண்டது, ஏனெனில் ஒரு அணிக்கு, நகர்த்துவது நகலெடுப்பதற்கு முற்றிலும் சமம்.

வரி

மற்றொரு உதாரணத்தைப் பார்ப்போம், வழக்கமான std::string . நாம் என்ன எதிர்பார்க்க முடியும்? நவீன செயலாக்கங்கள் இரண்டு வகையான சரங்களை வேறுபடுத்துகின்றன என்பதை நாங்கள் அறிவோம் (கட்டுரையில் இதைப் பற்றி விவாதித்தேன்) குட்டையானவைகளுக்கு, உள் தாங்கல் பயன்படுத்தப்படுகிறது, இது வழக்கமான C-வரிசை கரி ஆகும், ஆனால் நீண்டவை ஏற்கனவே குவியலில் வைக்கப்படும். குறுகிய வரிகளில் எங்களுக்கு ஆர்வம் இல்லை, ஏனென்றால்... முடிவு BDO போலவே இருக்கும், எனவே நீண்ட வரிகளில் கவனம் செலுத்துவோம்.

எனவே, ஒரு நீண்ட சரம் இருப்பதால், அதை நகர்த்துவது மிகவும் மலிவானதாக இருக்க வேண்டும் என்பது வெளிப்படையானது (சுட்டியை நகர்த்தவும்), எனவே சரத்தை நகர்த்துவது முடிவுகளை பாதிக்காது, மேலும் PPZ ஒரு முடிவைக் கொடுக்கும் என்ற உண்மையை நீங்கள் நம்பலாம். பிபிஎஸ்சியை விட மோசமாக இல்லை. நடைமுறையில் அதைச் சரிபார்த்து பின்வரும் முடிவுகளைப் பெறுவோம்:

இந்த "நிகழ்ச்சியை" விளக்குவதற்கு நாம் செல்வோம். ஏற்கனவே இருக்கும் சரத்தை ஏற்கனவே இருக்கும் சரத்தில் நகலெடுக்கும்போது என்ன நடக்கும்? ஒரு சிறிய உதாரணத்தைப் பார்ப்போம்:

முதலில் சரம்(64, "C"); சரம் இரண்டாவது(64, "N"); //... இரண்டாவது = முதல்;

எங்களிடம் இரண்டு 64-எழுத்து சரங்கள் உள்ளன, எனவே அவற்றை உருவாக்கும் போது போதுமான உள் தாங்கல் இல்லை, இதன் விளைவாக இரண்டு சரங்களும் குவியலில் ஒதுக்கப்படும். இப்போது நாம் முதல் முதல் இரண்டாவது வரை நகலெடுக்கிறோம். ஏனெனில் எங்கள் வரிசை அளவுகள் ஒரே மாதிரியானவை, வெளிப்படையாக எல்லா தரவையும் முதல் இடமளிக்க இரண்டாவது இடத்தில் போதுமான இடம் ஒதுக்கப்பட்டுள்ளது, எனவே இரண்டாவது = முதல்; ஒரு சாதாரணமான memcpy இருக்கும், அதற்கு மேல் எதுவும் இல்லை. ஆனால் நாம் சற்று மாற்றியமைக்கப்பட்ட உதாரணத்தைப் பார்த்தால்:

முதலில் சரம்(64, "C"); சரம் இரண்டாவது = முதல்;

பின்னர் operator= க்கு அழைப்பு இருக்காது, ஆனால் நகல் கட்டமைப்பாளர் அழைக்கப்படுவார். ஏனெனில் நாங்கள் ஒரு கட்டமைப்பாளருடன் கையாள்வதால், அதில் ஏற்கனவே உள்ள நினைவகம் இல்லை. அதை முதலில் தேர்ந்தெடுத்து பிறகு தான் முதலில் நகலெடுக்க வேண்டும் . அந்த. இது நினைவக ஒதுக்கீடு மற்றும் பின்னர் memcpy ஆகும். உங்களுக்கும் எனக்கும் தெரியும், உலகளாவிய குவியலில் நினைவகத்தை ஒதுக்குவது பொதுவாக ஒரு விலையுயர்ந்த செயலாகும், எனவே முதல் உதாரணத்திலிருந்து நகலெடுப்பதை விட இரண்டாவது உதாரணத்திலிருந்து நகலெடுப்பது மிகவும் விலை உயர்ந்ததாக இருக்கும். குவியல் நினைவக ஒதுக்கீட்டிற்கு அதிக விலை.

இதற்கும் எங்கள் தலைப்புக்கும் என்ன சம்பந்தம்? மிகவும் நேரடியான ஒன்று, ஏனெனில் முதல் எடுத்துக்காட்டு PPSC உடன் என்ன நடக்கிறது என்பதைக் காட்டுகிறது, இரண்டாவது PPZ இல் என்ன நடக்கிறது என்பதைக் காட்டுகிறது: PPZ க்கு ஒரு புதிய வரிசை எப்போதும் உருவாக்கப்படும், அதே நேரத்தில் PPSC க்கு ஏற்கனவே உள்ளதை மீண்டும் பயன்படுத்தப்படுகிறது. செயல்படுத்தும் நேரத்தின் வித்தியாசத்தை நீங்கள் ஏற்கனவே பார்த்திருக்கிறீர்கள், எனவே இங்கே சேர்க்க எதுவும் இல்லை.

PPP ஐப் பயன்படுத்தும் போது, ​​நாங்கள் சூழலுக்கு வெளியே செயல்படுகிறோம், எனவே அது வழங்கக்கூடிய அனைத்து நன்மைகளையும் பயன்படுத்த முடியாது என்ற உண்மையை இங்கே மீண்டும் எதிர்கொள்கிறோம். கோட்பாட்டு ரீதியான எதிர்கால மாற்றங்களின் அடிப்படையில் நாம் முன்னர் நியாயப்படுத்தியிருந்தால், உற்பத்தித்திறனில் ஒரு குறிப்பிட்ட தோல்வியை நாம் கவனிக்கிறோம்.

நிச்சயமாக, சரம் தனித்து நிற்கிறது என்று யாராவது என்னை எதிர்க்கலாம், மேலும் பெரும்பாலான வகைகள் அப்படி வேலை செய்யாது. இதற்கு நான் பின்வருவனவற்றிற்கு பதிலளிக்க முடியும்: முன்னர் விவரிக்கப்பட்ட அனைத்தும் ஒரு பேக் உறுப்புகளுக்கு குவியலில் நினைவகத்தை உடனடியாக ஒதுக்கும் எந்த கொள்கலனுக்கும் உண்மையாக இருக்கும். மேலும், மற்ற வகைகளில் என்ன சூழல்-உணர்திறன் மேம்படுத்தல்கள் பயன்படுத்தப்படுகின்றன என்பது யாருக்குத் தெரியும்?

இந்த பிரிவில் இருந்து என்ன எடுக்க வேண்டும்? நகர்த்துவது உண்மையில் மலிவானதாக இருந்தாலும், நகலெடுப்பதை நகலெடுப்பதற்கு பதிலாக நகல் + நகர்த்துவது எப்போதும் செயல்திறனின் அடிப்படையில் ஒப்பிடக்கூடிய முடிவைக் கொடுக்கும் என்று அர்த்தமல்ல.

சிக்கலான வகை

இறுதியாக, பல பொருள்களைக் கொண்டிருக்கும் ஒரு வகையைப் பார்ப்போம். இது ஒரு நபர் வகுப்பாக இருக்கட்டும், இது ஒரு நபருக்கு உள்ளார்ந்த தரவைக் கொண்டுள்ளது. பொதுவாக இது உங்கள் முதல் பெயர், கடைசி பெயர், அஞ்சல் குறியீடு போன்றவை. இவை அனைத்தையும் நீங்கள் சரங்களாகக் குறிப்பிடலாம், மேலும் நபர் வகுப்பின் புலங்களில் நீங்கள் வைக்கும் சரங்கள் குறுகியதாக இருக்கலாம் என்று கருதலாம். நிஜ வாழ்க்கையில், குறுகிய சரங்களை அளவிடுவது மிகவும் பயனுள்ளதாக இருக்கும் என்று நான் நம்பினாலும், இன்னும் முழுமையான படத்தை வழங்க வெவ்வேறு அளவுகளில் உள்ள சரங்களை இன்னும் பார்ப்போம்.

நான் 10 புலங்களைக் கொண்ட நபரையும் பயன்படுத்துவேன், ஆனால் இதற்காக நான் 10 புலங்களை நேரடியாக வகுப்பு அமைப்பில் உருவாக்க மாட்டேன். நபரை செயல்படுத்துவது ஒரு கொள்கலனை அதன் ஆழத்தில் மறைக்கிறது - இது சோதனை அளவுருக்களை மாற்றுவதை மிகவும் வசதியாக ஆக்குகிறது, நடைமுறையில் நபர் ஒரு உண்மையான வகுப்பாக இருந்தால் அது எவ்வாறு செயல்படும் என்பதில் இருந்து விலகாமல். இருப்பினும், செயல்படுத்தல் உள்ளது, நீங்கள் எப்போதும் குறியீட்டைச் சரிபார்த்து, நான் ஏதேனும் தவறு செய்திருந்தால் என்னிடம் சொல்லலாம்.

எனவே, செல்லலாம்: 10 வகை சரத்தின் புலங்களைக் கொண்ட நபர், PPSC மற்றும் PPZ ஐப் பயன்படுத்தி சேமிப்பகத்திற்கு மாற்றுவோம்:

நீங்கள் பார்க்க முடியும் என, செயல்திறனில் எங்களுக்கு ஒரு பெரிய வித்தியாசம் உள்ளது, இது முந்தைய பிரிவுகளுக்குப் பிறகு வாசகர்களுக்கு ஆச்சரியமாக இருக்கக்கூடாது. நபர் வகுப்பு "உண்மையானது" என்று நான் நம்புகிறேன், அத்தகைய முடிவுகள் சுருக்கமாக நிராகரிக்கப்படாது.

மூலம், நான் இந்த கட்டுரையை தயார் செய்யும் போது, ​​நான் மற்றொரு உதாரணத்தை தயார் செய்தேன்: பல std :: செயல்பாட்டு பொருள்களைப் பயன்படுத்தும் ஒரு வகுப்பு. எனது யோசனையின்படி, இது PPZ ஐ விட PPSC இன் செயல்திறனில் ஒரு நன்மையைக் காட்ட வேண்டும், ஆனால் அது நேர்மாறாக மாறியது! ஆனால் நான் இந்த உதாரணத்தை இங்கே கொடுக்கவில்லை, ஏனெனில் முடிவுகள் எனக்கு பிடிக்கவில்லை என்பதற்காக அல்ல, ஆனால் அத்தகைய முடிவுகள் ஏன் பெறப்பட்டன என்பதைக் கண்டுபிடிக்க எனக்கு நேரம் இல்லை என்பதால். ஆயினும்கூட, களஞ்சியத்தில் (அச்சுப்பொறிகள்), சோதனைகளில் குறியீடு உள்ளது - யாராவது அதைக் கண்டுபிடிக்க விரும்பினால், ஆராய்ச்சியின் முடிவுகளைப் பற்றி நான் மகிழ்ச்சியடைவேன். இந்த உதாரணத்திற்கு நான் பின்னர் திரும்ப திட்டமிட்டுள்ளேன், இந்த முடிவுகளை யாரும் எனக்கு முன் வெளியிடவில்லை என்றால், நான் அவற்றை ஒரு தனி கட்டுரையில் பரிசீலிப்பேன்.

முடிவுகள்

எனவே மதிப்பின் மூலம் கடந்து செல்வதன் பல்வேறு நன்மை தீமைகளைப் பார்த்தோம். நாங்கள் சில எடுத்துக்காட்டுகளைப் பார்த்தோம் மற்றும் இந்த எடுத்துக்காட்டுகளில் இரண்டு முறைகளின் செயல்திறனைப் பார்த்தோம். நிச்சயமாக, இந்த கட்டுரை முழுமையானது அல்ல, ஆனால், என் கருத்துப்படி, எந்த முறையைப் பயன்படுத்துவது சிறந்தது என்பதைப் பற்றிய சுயாதீனமான மற்றும் தகவலறிந்த முடிவை எடுக்க போதுமான தகவல்கள் இதில் உள்ளன. யாராவது எதிர்க்கலாம்: "ஏன் ஒரு முறையைப் பயன்படுத்த வேண்டும், பணியிலிருந்து தொடங்குவோம்!" பொதுவாக இந்த ஆய்வறிக்கையை நான் ஏற்றுக்கொண்டாலும், இந்த சூழ்நிலையில் நான் அதை ஏற்கவில்லை. ஒரு மொழியில் வாதங்களைக் கடந்து செல்ல ஒரே ஒரு வழி மட்டுமே இருக்க முடியும் என்று நான் நம்புகிறேன். எது இயல்புநிலை.

இயல்புநிலை என்றால் என்ன? இதன் பொருள் என்னவென்றால், நான் ஒரு செயல்பாட்டை எழுதும்போது, ​​வாதத்தை எவ்வாறு அனுப்ப வேண்டும் என்று நான் நினைக்கவில்லை, நான் "இயல்புநிலை" ஐப் பயன்படுத்துகிறேன். C++ மொழி என்பது பலர் தவிர்க்கும் சிக்கலான மொழியாகும். மேலும் என் கருத்துப்படி, சிக்கலானது மொழியில் இருக்கும் மொழி கட்டமைப்பின் சிக்கலான தன்மையால் அல்ல (ஒரு வழக்கமான புரோகிராமர் அவற்றை ஒருபோதும் சந்திக்க முடியாது), ஆனால் மொழி உங்களை நிறைய சிந்திக்க வைக்கிறது: நான் விடுவித்தேன் நினைவகம், இந்த செயல்பாட்டை இங்கே பயன்படுத்துவது விலை உயர்ந்ததா?

பல புரோகிராமர்கள் (C, C++ மற்றும் பலர்) 2011க்குப் பிறகு தோன்றத் தொடங்கிய C++ மீது அவநம்பிக்கை மற்றும் பயம் கொண்டவர்கள். மொழி மிகவும் சிக்கலானதாகி வருகிறது, “குருக்கள்” மட்டுமே இப்போது அதில் எழுத முடியும், போன்ற பல விமர்சனங்களை நான் கேள்விப்பட்டிருக்கிறேன். தனிப்பட்ட முறையில், இது அவ்வாறு இல்லை என்று நான் நம்புகிறேன் - மாறாக, குழு மொழியை ஆரம்பநிலைக்கு மிகவும் நட்பாக மாற்றுவதற்கு நிறைய நேரம் ஒதுக்குகிறது, இதனால் புரோகிராமர்கள் மொழியின் அம்சங்களைப் பற்றி குறைவாக சிந்திக்க வேண்டும். எல்லாவற்றிற்கும் மேலாக, நாம் மொழியுடன் போராட வேண்டியதில்லை என்றால், பணியைப் பற்றி சிந்திக்க நமக்கு நேரம் இருக்கிறது. இந்த எளிமைப்படுத்தல்களில் ஸ்மார்ட் பாயிண்டர்கள், லாம்ப்டா செயல்பாடுகள் மற்றும் மொழியில் தோன்றிய பல உள்ளன. அதே சமயம், இப்போது நாம் அதிகம் படிக்க வேண்டும் என்ற உண்மையை நான் மறுக்கவில்லை, ஆனால் படிப்பதில் என்ன தவறு? அல்லது மற்ற பிரபலமான மொழிகளில் கற்க வேண்டிய மாற்றங்கள் எதுவும் நடக்கவில்லையா?

மேலும், பதில் சொல்லக்கூடிய ஸ்னோப்கள் இருப்பார்கள் என்பதில் எனக்கு எந்த சந்தேகமும் இல்லை: “நீங்கள் சிந்திக்க விரும்பவில்லையா? பின்னர் PHP இல் எழுதவும். அப்படிப்பட்டவர்களுக்கு நான் பதில் சொல்ல விரும்பவில்லை. கேம் ரியாலிட்டியில் இருந்து ஒரு உதாரணத்தை மட்டும் தருகிறேன்: ஸ்டார்கிராஃப்டின் முதல் பகுதியில், ஒரு கட்டிடத்தில் ஒரு புதிய தொழிலாளி உருவாக்கப்பட்டால், அவர் கனிமங்களை (அல்லது வாயு) பிரித்தெடுக்கத் தொடங்க, அவர் கைமுறையாக அங்கு அனுப்பப்பட வேண்டும். மேலும், ஒவ்வொரு தாதுப் பொதியும் ஒரு வரம்பைக் கொண்டிருந்தது, அதை அடைந்தவுடன் தொழிலாளர்களின் அதிகரிப்பு பயனற்றது, மேலும் அவை ஒன்றுக்கொன்று குறுக்கிட்டு, உற்பத்தியை மோசமாக்கும். இது ஸ்டார்கிராஃப்ட் 2 இல் மாற்றப்பட்டது: தொழிலாளர்கள் தானாக கனிமங்களை (அல்லது எரிவாயு) சுரங்கப்படுத்தத் தொடங்குகிறார்கள், மேலும் தற்போது எத்தனை தொழிலாளர்கள் சுரங்கம் செய்கிறார்கள் மற்றும் இந்த வைப்புத்தொகையின் வரம்பு எவ்வளவு என்பதையும் இது குறிக்கிறது. இது தளத்துடனான வீரரின் தொடர்புகளை பெரிதும் எளிதாக்கியது, விளையாட்டின் மிக முக்கியமான அம்சங்களில் கவனம் செலுத்த அனுமதிக்கிறது: ஒரு தளத்தை உருவாக்குதல், படைகளைக் குவித்தல் மற்றும் எதிரியை அழித்தல். இது ஒரு சிறந்த கண்டுபிடிப்பு என்று தோன்றுகிறது, ஆனால் இது இணையத்தில் தொடங்கியது! மக்கள் (அவர்கள் யார்?) கேம் "திரும்பியதாக" மற்றும் "அவர்கள் ஸ்டார்கிராஃப்டைக் கொன்றார்கள்" என்று கத்த ஆரம்பித்தனர். வெளிப்படையாக, இதுபோன்ற செய்திகள் சில "எலைட்" கிளப்பில் இருக்க விரும்பும் "ரகசிய அறிவைக் காப்பவர்கள்" மற்றும் "உயர் ஏபிஎம்மின் திறமையாளர்களிடமிருந்து" மட்டுமே வர முடியும்.

எனவே, எங்கள் தலைப்புக்குத் திரும்புகையில், குறியீட்டை எவ்வாறு எழுதுவது என்பதைப் பற்றி நான் குறைவாக சிந்திக்க வேண்டும், உடனடி சிக்கலைத் தீர்ப்பது பற்றி நான் அதிக நேரம் சிந்திக்க வேண்டும். நான் எந்த முறையைப் பயன்படுத்த வேண்டும் என்பதைப் பற்றி சிந்திப்பது - பிபிஎஸ்சி அல்லது பிபிஇசட் - சிக்கலைத் தீர்ப்பதில் எனக்கு ஒரு அயோட்டாவைக் கொண்டு வரவில்லை, எனவே இதுபோன்ற விஷயங்களைப் பற்றி சிந்திக்க நான் மறுக்கிறேன் மற்றும் ஒரு விருப்பத்தைத் தேர்வு செய்கிறேன்: மாறிலியைக் குறிப்பதன் மூலம் கடந்து செல்வது. ஏன்? ஏனெனில் பொதுச் செயல்பாட்டில் PPPக்கு எந்த நன்மையும் இல்லை, மேலும் சிறப்பு வழக்குகள் தனித்தனியாகக் கருதப்பட வேண்டும்.

இது ஒரு சிறப்பு வழக்கு, இது சில முறைகளில் பிபிஎஸ்சி ஒரு இடையூறாக மாறுவதைக் கவனித்த பிறகு, பிபிஇசட்டுக்கு பரிமாற்றத்தை மாற்றுவதன் மூலம், செயல்திறனில் ஒரு முக்கியமான அதிகரிப்பு கிடைக்கும், இதைப் பயன்படுத்த நான் தயங்கவில்லை. PPZ. ஆனால் இயல்பாக, வழக்கமான செயல்பாடுகளிலும், கன்ஸ்ட்ரக்டர்களிலும் PPSC ஐப் பயன்படுத்துவேன். முடிந்தால், இந்த குறிப்பிட்ட முறையை முடிந்தவரை விளம்பரப்படுத்துவேன். ஏன்? புரோகிராமர்களில் சிங்கத்தின் பங்கு அதிக அறிவு இல்லாததால் (கொள்கையில், அல்லது இன்னும் விஷயங்களை ஊசலாடவில்லை) மற்றும் அவர்கள் வெறுமனே ஆலோசனையைப் பின்பற்றுவதால் PPP ஐ ஊக்குவிக்கும் நடைமுறை தீயது என்று நான் நினைக்கிறேன். கூடுதலாக, பல முரண்பட்ட ஆலோசனைகள் இருந்தால், அவர்கள் எளிமையான ஒன்றைத் தேர்வு செய்கிறார்கள், மேலும் இது குறியீட்டில் அவநம்பிக்கைக்கு வழிவகுக்கிறது, ஏனெனில் யாரோ எங்காவது ஏதாவது கேட்டிருக்கிறார்கள். ஆம், இவர் தான் சொல்வது சரி என்பதை நிரூபிக்க ஆபிரகாம்ஸின் கட்டுரைக்கான இணைப்பையும் வழங்க முடியும். பின்னர் நீங்கள் உட்கார்ந்து, குறியீட்டைப் படித்து சிந்தியுங்கள்: அளவுரு இங்கே மதிப்பால் அனுப்பப்பட்டது, ஏனெனில் இதை எழுதிய புரோகிராமர் ஜாவாவிலிருந்து வந்தவர், நிறைய “ஸ்மார்ட்” கட்டுரைகளைப் படித்தார், அல்லது உண்மையில் ஒரு தேவை இருக்கிறதா? தொழில்நுட்ப விவரக்குறிப்பு?

PPSC படிக்க மிகவும் எளிதானது: நபர் C++ இன் "நல்ல வடிவத்தை" தெளிவாக அறிந்திருக்கிறார், மேலும் நாங்கள் முன்னேறுகிறோம் - பார்வை நீடிக்காது. பிபிஎஸ்சியைப் பயன்படுத்தும் நடைமுறை பல ஆண்டுகளாக சி++ புரோகிராமர்களுக்குக் கற்பிக்கப்படுகிறது, அதைக் கைவிட காரணம் என்ன? இது என்னை மற்றொரு முடிவுக்கு இட்டுச் செல்கிறது: ஒரு முறை இடைமுகம் PPP ஐப் பயன்படுத்தினால், அது ஏன் என்று ஒரு கருத்தும் இருக்க வேண்டும். மற்ற சந்தர்ப்பங்களில், PPSC விண்ணப்பிக்க வேண்டும். நிச்சயமாக, விதிவிலக்கு வகைகள் உள்ளன, ஆனால் நான் அவற்றை இங்கு குறிப்பிடவில்லை, ஏனெனில் அவை குறிக்கப்படுகின்றன: string_view , initializer_list , பல்வேறு மறு செய்கைகள் போன்றவை. ஆனால் இவை விதிவிலக்குகள், திட்டத்தில் என்ன வகைகள் பயன்படுத்தப்படுகின்றன என்பதைப் பொறுத்து பட்டியல் விரிவடையும். ஆனால் சி++98 இலிருந்து சாராம்சம் அப்படியே உள்ளது: முன்னிருப்பாக நாம் எப்போதும் PPCS ஐப் பயன்படுத்துகிறோம்.

std::string க்கு சிறிய சரங்களில் எந்த வித்தியாசமும் இருக்காது, இதைப் பற்றி பின்னர் பேசுவோம்.



பகிர்