PDA

View Full Version : مفهم معرفی این کلاس چیه؟ ( forward ... )



hosseinam1370
یک شنبه 06 اردیبهشت 1394, 10:49 صبح
دوستان داشتم آموزشهای کیوت رو دنبال میکردم ، که یه سوال c++ برام پیش اومد ،در این کد(فایل هدر) :

#include <qwidget.h>
#include <QPushButton>
class QLineEdit;// manzor az in kelass chiye ? aya shabihe be include amal mikone?
class myWidget : public QWidget

{
Q_OBJECT
QLineEdit *led;
public:
myWidget (QWidget *parent = 0);

private slots:
void mySlots();

signals:
void mySignal (int);

};

آقای سعید دادخواه در آموزش هاش گفته بود که ، (در اون خطی که کامنت زدم) این کلاس رو forward نمیدونم چی میکنیم ،(البته من کلمه ی بعدش رو متوجه نشدم)
حالا خاستم ، بدونم این یه کلاس از قبل تعریف شده هست ، و وجود داره ، حالا چه دلیلی داره که ما بیایم دوباره اینو اینطوری به کد اضافه کنیم؟و این الان چیکار میکنه؟

با تشکر.

rahnema1
یک شنبه 06 اردیبهشت 1394, 15:39 عصر
سلام
بحث forward declaration
شما اینجا محتوای یک فایل هدر مثلا به نام myhedaer.h را گذاشتید
برای اینکه بتونیم از یک نام در برنامه استفاده کنیم لازمه که اون نام را قبلا اعلان یا تعریف کرده باشیم
اگر دقت کنید در یک جای برنامه از کلاسی به نام QLineEdit استفاده می شه

QLineEdit *led;

که حتما لازمه از قبلش برای برنامه مشخص باشه که این QLineEdit از کجا اومده
از طرف دیگه led یک اشاره گر به یک شیء QLineEdit هست و یک قانون داریم که اگه قرار باشه از اشاره گر به یک کلاس استفاده بشه لازم نیست برنامه تعریف کامل اون کلاس را بدونه بلکه فقط کافیه نام اون کلاس از طریق اعلان به برنامه معرفی بشه که این کار را انجام می دهیم:

class QLineEdit;

تعریف کلاس QLineEdit از طریق هدری به نام QLineEdit قابل دسترسی هست اما چرا ما QLineEdit را include نمی کنیم که دیگه نخواهیم نام اون را اعلان کنیم ؟ مثلا این کار کنیم:
#include <QLineEdit>
برای اینکه myhedaer.h کامپایل بشه فقط کافیه نام کلاس اعلان بشه و include کردن موجب افزایش زمان کامپایل برنامه میشه. به عنوان یک قاعده لازمه که هنگام کامپایل وابستگی بین فایلها را در کامپایل به حداقل برسونیم
بعدا در فایل سورس مثلا mysource.cpp می آییم QLineEdit را include می کنیم
این نکاتی که ذکر کردم در خصوص include کردن و قواعد مربوط به اون را می تونید در این منبع (http://www.stroustrup.com/JSF-AV-rules.pdf) که توسط Stroustrup نوشته شده مطالعه کنید

hosseinam1370
یک شنبه 06 اردیبهشت 1394, 20:05 عصر
فوقالعاده بود توضیح.

chikar
پنج شنبه 24 اردیبهشت 1394, 09:02 صبح
بحث forward declaration

برای اینکه myhedaer.h کامپایل بشه فقط کافیه نام کلاس اعلان بشه و include کردن موجب افزایش زمان کامپایل برنامه میشه. به عنوان یک قاعده لازمه که هنگام کامپایل وابستگی بین فایلها را در کامپایل به حداقل برسونیم
بعدا در فایل سورس مثلا mysource.cpp می آییم QLineEdit را include می کنیم

این بحث رو من خیلی تو کتابخونه های بزرگ دیدم، یه سوال دیگه غیر از مطلبی که پاسخ دادید برام پیش اومده :
به فرض هم تو فایل cpp. ما include کنیم اونجا هم که کامپایل میشه و در نتیجه اونجا افزایش زمان کامپایل انجام می شه؟
یعنی فقط تو فایل .h باعث افزایش زمان کامپایل می شه؟ چه فرقی داره ؟؟
بعد هم تو کتابخونه های بزرگ، سورس از قبل کامپایل شده و تبدیل به یه فایل dll شده و فقط هنگام include به برنامه لینک میشه!!!

chikar
پنج شنبه 24 اردیبهشت 1394, 09:21 صبح
سلام
بحث forward declaration

علاوه بر سوالم در پست قبلی یه سوال دیگه هم اینجا دارم!
100% این مساله رو بهتر از من می دونید فقط من باب طرح سوالم این توضیح رو می دم
من همیشه فکر می کردم که دلیلش ترتیب نوشتن کلاس هاست، نه افزایش زمان کامپایل! کد ساده زیر رو ببینید :
در کد زیر اگر بخواهیم نمونه ای از کلاس B داخل کلاس A بسازیم، چون این کلاس بعد از کلاس A است، تنها راهش این است که کلاس B را در بالای کلاس A اعلان کنیم، و فقط هم می توانیم یک اشاره گر به کلاس B ایجاد کنیم، از اعضای کلاس B هم فقط می توانیم در بخش تعریف پس از خود کلاس B استفاده کنیم (مثل متد Funck)


class B;
class A
{
public:
B *b;
void funck();
};
class B
{
public:
int pub_var;
};

void A::funck()
{
b->pub_var = 7;
}


حالا می خوام بدونم، ممکن هست یه دلیلش هم این باشه؟

rahnema1
پنج شنبه 24 اردیبهشت 1394, 17:52 عصر
ببینید اون pdf که گذاشتم داخلش تعدادی اصول و قواعد یا استایل های برنامه نویسی هست که توسط Stroustrup که خالق زبان ++c هست نوشته شده
قاعده 36 : وابستگی در کامپایل باید به حداقل برسد
قاعده 37: فایلهای هدر فقط باید هدرهایی را include کنند که برای کامپایلشون مورد نیازه. فایلهایی که فقط توسط فایل cpp مرتبط استفاده می شوند باید include اونها در فایل cpp باشه نه در فایل h
قاعده 38: اعلان کلاسهایی که فقط توسط اشاره گر یا ارجاع مورد استفاده قرار می گیرند باید توسط forward declaration انجام بشه. این forward declaration ها هم باید داخل هدری باشه که اون هدر فقط شامل forward declaration هست.
این اصول و استایل ها معمولا در کتابخانه ها رعایت می شه
علت اینها را هم وابستگی کمتر و نگهداری بهتر برنامه و کمتر شدن زمان کامپایل و رعایت اصل loose coupling هست که اینها را ذکر کرده
برگردیم به سوال:


به فرض هم تو فایل cpp. ما include کنیم اونجا هم که کامپایل میشه و در نتیجه اونجا افزایش زمان کامپایل انجام می شه؟
یعنی فقط تو فایل .h باعث افزایش زمان کامپایل می شه؟ چه فرقی داره ؟؟
بعد هم تو کتابخونه های بزرگ، سورس از قبل کامپایل شده و تبدیل به یه فایل dll شده و فقط هنگام include به برنامه لینک میشه!!!

طبیعیه که هر جا include بشه زمان کامپایل افزایش پیدا می کنه
فقط یک نکته اینه که بر طبق مثال اول من می خواهم از کلاس myWidget در یک سری تابعها یا کلاسهای دیگه استفاده کنم خب کافیه که هدر اون را include کنم اگه این هدر myheader.h اومده باشه هدرهای دیگه را include کرده باشه به ازای استفاده هایی که از myheader.h کردم لازمه اون هدر ها هم پیش پردازش و کامپایل بشه در صورتی که اگر هدرهای مورد نیاز را در فایل mysource.cpp داخل کرده بودم تنها یک بار برای کامپایل cpp لازم بود اون هدرها پیش پردازش و کامپایل بشن
همین هدر ها هم شاید شامل صدها یا هزاران خط کد باشن
برفرض اینکه فایلهای cpp هم کامپایل شه باشند موقع کامپایل برنامه ما خود خواندن فایلهای هدر و پیش پردازش و .. اونها زمان می بره

rahnema1
پنج شنبه 24 اردیبهشت 1394, 17:55 عصر
در کد زیر اگر بخواهیم نمونه ای از کلاس B داخل کلاس A بسازیم، چون این کلاس بعد از کلاس A است، تنها راهش این است که کلاس B را در بالای کلاس A اعلان کنیم، و فقط هم می توانیم یک اشاره گر به کلاس B ایجاد کنیم، از اعضای کلاس B هم فقط می توانیم در بخش تعریف پس از خود کلاس B استفاده کنیم (مثل متد Funck)

این که همون قضیه شد قبلا هم اشاره کردم که:
یک قانون داریم که اگه قرار باشه از اشاره گر به یک کلاس استفاده بشه لازم نیست برنامه تعریف کامل اون کلاس را بدونه بلکه فقط کافیه نام اون کلاس از طریق اعلان به برنامه معرفی بشه