با دانش کنونی ما، بهروزرسانی یک متغیر به کمک یک تابع کمی دشوار است. هر آرگومان تابع مانند یک کپی رفتار میشود و مقدار اصلی را تغییر نمیدهد. بسته به اندازهی نوع دادهای که تعریف میکنید، این موضوع میتواند پیامدهای جدی برای کارایی کد شما داشته باشد.
int adjust_salary(int base, int kids) {
return base + kids * 500;
}
int now_a_mother_of_twins{2500};
adjust_salary(now_a_mother_of_twins, 2);
// now_a_mother_of_twins is still 2500
now_a_mother_of_twins = adjust_salary(now_a_mother_of_twins, 2);
// now_a_mother_of_twins is now 3500
References را میتوان نامهای مستعار در نظر گرفت، تغییرات در آنها بر متغیر اصلی اثر میگذارد.
References در اعلان نوع از یک آمپرسند (&) استفاده میکنند.
int balance{1000};
int& budget{balance};
int pro_computer_wheels{699};
budget -= pro_computer_wheels;
// budget is now 301;
// balance is also 301;
اتصالدهی دوباره (تغییر اتصال یک reference) امکانپذیر نیست.
نمیتوانید یک reference مقداردهینشده داشته باشید.
References را باید با یک متغیر موجود مقداردهی کرد.
int main_acc{1'000'000};
int side_acc{-20};
int& savings{main_acc};
// => main_acc and savings are 1'000'000
// try to reseat savings to use main account
savings = side_acc;
// savings and main_acc are now -20
// as this uses the **value** of side_acc
savings += 20;
// savings and main_acc are now 0, side_acc is still -20
int& future_budget;
// => compiler error, reference must be bound!
voidبا قدرت references شاید دیگر نیازی نداشته باشید که از یک تابع مقداری را برگردانید.
در این حالت، void بهعنوان نوع بازگشتی به کار میرود.
void increase_power(int& level) {
level += 500;
}
int goku{8700};
increase_power(goku);
// goku's power level?
// It's over 9000!
یک مدرسهی محلی نزدیک شما انجمن دانشآموزی بسیار فعالی دارد. انجمن دانشآموزی توسط یک رئیس اداره میشود و هر ۲ سال یکبار، برای انتخاب رئیس جدید انتخابات برگزار میشود.
در انتخابات امسال تصمیم گرفته شد که به یک سامانهی دیجیتال جدید برای شمارش آرا نیاز است. مدرسه برای ساختن این سامانهی جدید به کمک شما نیاز دارد.
ElectionResult
سامانهی جدید به راهی نیاز خواهد داشت که تعداد آرا را از یک شمارنده به دست آورد.
struct نتیجهی انتخابات از قبل برای شما ساخته شده است و به این شکل تعریف میشود:
struct ElectionResult {
// Name of the candidate
std::string name{};
// Number of votes the candidate has
int votes{};
};
چون همهی اعضای struct عمومی هستند، نیازی نیست برای مقداردهی اولیه به یک شیء ElectionResult یک constructor بنویسید.
بهجای آن میتوانید از initializer list استفاده کنید:
ElectionResult hamilton{"Alex", 1804};
// => the hamilton object was initialized with the name "Alex" and 1804 votes.
تابعی به نام vote_count بسازید که یک ارجاع به ElectionResult را به عنوان آرگومان میگیرد و تعداد آرا در ElectionResult را برمیگرداند.
vote_count(hamilton);
// => 1804
ElectionResult
بالاخره وقت پردازش آرا رسیده است!
حالا به راهی نیاز دارید که آرا در یک ElectionResult را افزایش دهد.
تابعی void به نام increment_vote_count بسازید که یک ارجاع به ElectionResult و یک تعداد آرا را به عنوان آرگومان میگیرد و ElectionResult را به اندازهی آن تعداد آرا افزایش میدهد.
ElectionResult burr{"Aaron " 1801};
increment_vote_count(burr, 3);
vote_count(burr);
// => 1804
مدرسه آرا را تحویل داد و حالا وقت بررسی نتایج برای یافتن برنده است.
تابعی به نام determine_result بسازید که یک ارجاع به شمارش نهایی میگیرد و یک ارجاع به ElectionResult رئیس جدید را برمیگرداند.
همچنین باید اسم برنده را با افزودن پیشوند «President» به آن تغییر دهد.
شمارش نهایی در قالب یک reference به std::vector<ElectionResult> داده میشود؛ برداری که ElectionResults همهی نامزدهای شرکتکننده را در خود دارد.
ElectionResult sanchez{"Pedro", 471};
ElectionResult wheatley{"Summer", 340};
std::vector<ElectionResult> final_count{sanchez, wheatley};
ElectionResult& winner = determine_result(final_count);
winner.name;
// => "President Pedro"
برای ساده نگه داشتن کار، میتوانید موارد زیر را فرض کنید:
vector حداقل یک عنصر دارد.