المپدیا

دانش‌نامه‌ی المپیاد کامپیوتر ایران

ابزار کاربر

ابزار سایت


آموزش:برنامه نویسی:سربارگذاری نام توابع

سربارگذاری

تعریف

با استفاده از ویژگی سربارگذاری چند تابع میتوانند نام یکسانی داشته باشند در حالی که تعریف پارامتر های آن های متفاوت است . این توابع میتوانند نوع خروجی متفاوت داشته باشند ولی این دلیل بر تمایر آن ها نمیشود بلکه تمایز در لیست پارامتر ها است. مثال زیر را در نظر بگیرید:

overload.cpp
#include<iostream>
using namespace std;
void f(int a){
	cout<<"in f(int a)"<<endl;
}
void f(int a,int b){
	cout<<"in f(int a,int b)"<<endl;
}
void f(int a,double b){
	cout<<"in f(int a,double b)"<<endl;
}
int main(){
	f(1);
	f(1,2);
	f(1,2.0);
	return 0;
}
/* OUTPUT:
in f(int a)
in f(int a,int b)
in f(int a,double a)
*/

در کد بالا تابغ $f$ سه بار با لیست پارامتر های مختلف تعریف شده است کامپایلر با استفاده از لیست پارامتر متوجه میشود که یک فراخوانی مربوط به کدام یک از تعاریف است. توجه کنید که تمایز در نوع خروجی منجر به سربارگذاری نمیشود بنابراین برای مثال تکه کد زیر دارای خطای کامپایلر است:

int f(int a){return 0;}
double f(int a){return 0.0;}

ابهام

در مواقعی کامپایلر نمیتواند موقع فراخوانی تابع مورد نظر را به طور یکتا تشخیص دهد و در نتیجه دچار ابهام شده و با خطای کامپایلر مواجه میشویم. این موضوع را در قالب مثال بررسی میکنیم.

مثال اول

کد زیر را در نظر بگیرید :

ambiguity.cpp
#include<iostream>
using namespace std;
void f(double a){return;}
void f(float a){return;}
int main(){
	f(10.0);   // OK !
	f(10);     // Compile error here !
	return 0;
}

در خط اول $f$ با مقداری اعشاری فراخوانی شده است که به طور پیشفرض در $C++$ از نوع $double$ در نظر گرفته شده و بدون هیچ مشکلی تابع $f$ مورد نظر با ورودی $double$ فراخوانی میشود اما در خط دوم $f$ با مقداری $int$ فراخوانی میشود و کامپایلر نمیتواند تشخیص دهد که آن را به $double$ تبدیل کند یا به $float$ و در نتیجه خطای کامپایل رخ میدهد.

مثال دوم

این مشکل به هنگام استقاده از مقادیر پیشفرض و سربارگذاری به صورت همزمان رخ میدهد. کد زیر را درنظر بگیرید:

ambiguity2.cpp
#include<iostream>
using namespace std;
void f(int a){return;}
void f(int a,int b=1){return;}
int main(){
	f(10);     // Compile error here !
	return 0;
}

در اینجا کامپایلر نمیتواند تشخیص دهد که منظور تابع یک پارامتری اول است یا تابع دو پارامتریی که برای متغیر دوم مقدار پیشفرض باید در نظر گرفته شود بنابراین با خطای کامپایل مواجه میشویم.


ابزار صفحه