PDA

View Full Version : یک مشکل عجیب و راه حل عجیب تر اون!



omid_Ahmadi
جمعه 06 خرداد 1384, 17:17 عصر
سلام
من میخواستم یه برنامه با ++C بنویسم که در اون یک کلاس تعریف کنم که یکی از Constructor های کلاس ارجاع شیی از نوع خود کلاس را به عنوان پارامتر بگیره و از کد زیر استفاده کردم:


class date
{
public: date(date &);
date();
};
date::date(date &t){}
date::date(){}
main()
{
date a();
date b(a);
}

ولی وقتی این کد رو در Borland C++ 5 کامپایل کردم خطای زیر رو دیدم:


Could not find a match for date::date(date (*)())

که مربوط به خط 11 برنامه یود.
ولی وقتی کد رو به صورت زیر اصلاح کردم (به طور اتفاقی البته) خطا رفع شد:


class date
{
public: date(date &);
date();
};
date::date(date &t){}
date::date(){}
main()
{
date a ;
date b(a);
}

چرا؟ :گیج:

Inprise
جمعه 06 خرداد 1384, 18:12 عصر
اگر میخواهی از Default constructor استفاده کنی date a کافی است .

omid_Ahmadi
جمعه 06 خرداد 1384, 20:04 عصر
اگر میخواهی از Default constructor استفاده کنی date a کافی است .

درسته ولی در برنامه اولی من از Constructorای استفاده کرده بودم که هیچ آرگومانی نمیگرفت. با برداشتن پرانتزها هم که همون Constructor فراخوانی میشه!

Inprise
جمعه 06 خرداد 1384, 23:02 عصر
منظورت رو نمیفهمم ؛ وقتی شی ای رو صریحا" تعریف میکنی ، از سازندهء پیش فرضش برای ساختن اون استفاده میشه و اگر سازنده های متعددی وجود داشته باشه میتونی موقع ساختن یک نسخه از کلاس پارامترهای مربوطه رو مطابق نیاز ت ارسال کنی . کد دوم درسته ؛ خلاص

محمد میرمصطفی
جمعه 06 خرداد 1384, 23:48 عصر
کلاسی که توش هستی هنوز implementionش تموم نشده، پس تعریف نشده. راه حل:

class ca;
class ca{
private: ca* a;
};
با این کار کلاس رو predefine کردی.

omid_Ahmadi
شنبه 07 خرداد 1384, 08:48 صبح
وقتی من پرانتز ها رو جلوی عبارت date a قرار نمیدم constructorی که هیچ پارامتری نمیگیره فراخوانی میشه و شیی ایجاد میشه. وقتی پرانتزها رو قرار میدم هم باز همون constructor قبلی فراخوانی میشه(constructorی که هیچ پارامتری نمیگیره) ولی در حالت اول در ارسال شیی a به constructor دوم برای ایجاد شیی b مشکلی نداره و در حالت دوم مشکل داره در صورتی که در هر دو حالت شیی با یک constructor ایجاد شده نه با دو constructor مجزا.
در کل اگر پرانتزها باشند از constructor دوم استفاده میشه و اگر هم نباشند به قول شما از constructor پیش فرض ( که همون constructor دوم هست) استفاده میشه!

Blaster
شنبه 07 خرداد 1384, 11:33 صبح
دوست عزیز، من فکر می کنم زمانی که شما از دستور زیر استفاده می کنید

date a();
کامپایلر اون رو به عنوان تعریف یک تابع جدید با اسم () a و مقدار برگشتی date تشخیص میده و نه به عنوان یک نسخه از کلاس date .
البته هیچ سند و مدرکی برای اثبات این موضوع ندارم و فقط به نظرم اومد که این علتش باشه.
بد نیست اینها رو هم امتحان کنید اگه Error نداد شاید بتونه اون چیزهایی رو که گفتم روشن کنه.

date a();
date* d();
date& e();

karim_medusa
شنبه 07 خرداد 1384, 13:03 عصر
دوست عزیز، من فکر می کنم زمانی که شما از دستور زیر استفاده می کنید

date a();
کامپایلر اون رو به عنوان تعریف یک تابع جدید با اسم () a و مقدار برگشتی date تشخیص میده و نه به عنوان یک نسخه از کلاس date .
البته هیچ سند و مدرکی برای اثبات این موضوع ندارم و فقط به نظرم اومد که این علتش باشه.
بد نیست اینها رو هم امتحان کنید اگه Error نداد شاید بتونه اون چیزهایی رو که گفتم روشن کنه.

date a();
date* d();
date& e();

دوست عزیز ! استنتاج شما کاملا درسته!
و مدرکش هم همون خطایی که کامپایلر گرفته است . نوشته همچین سازنده ای واسه کلاس با این نوع پارامتر ورودی که تابع است وجود ندارد.


Could not find a match for date::date(date (*)())

omid_Ahmadi
شنبه 07 خرداد 1384, 21:08 عصر
کامپایلر اون رو به عنوان تعریف یک تابع جدید با اسم () a و مقدار برگشتی date تشخیص میده و نه به عنوان یک نسخه از کلاس date .
البته هیچ سند و مدرکی برای اثبات این موضوع ندارم و فقط به نظرم اومد که این علتش باشه.
بد نیست اینها رو هم امتحان کنید اگه Error نداد شاید بتونه اون چیزهایی رو که گفتم روشن کنه.

دقیقا درسته کامپایلر در حالت اول اون رو به عنوان یک تابع در نظر میگرفت.
خیلی ممنون :)

Pars Giga
جمعه 13 خرداد 1384, 08:51 صبح
:confy2: