PDA

View Full Version : علت ساخت دو فایل برای هر کلاس در c++ چیست؟



alireza es
جمعه 10 مرداد 1393, 23:40 عصر
با عرض سلام.
ما تو زبان هایی مثل دلفی و C++‎‎‎‎‎‎ اول میاییم یه تابع رو در یک کلاس اعلان میکنیم ،بعد اونو تو یه جای دیگه تعریف میکنیم
اما تو زبانی مثل جاوا،تابع رو تو جایی که نوعش و نامش رو مشخص کردیم،تعریف و مقدار دهی میکنیم میکنیم .
توی C++‎‎‎‎‎‎ حتی دو فایل برای هر کلاس ایجاد میکنیم.(هدر و سورس)
سوالم اینه که چرا از این روش استفاده میکنیم؟؟ این روش چه امکاناتی و مزایایی رو برای ما داره؟؟ در ضمن میتونیم مثل جاوا عمل کنیم؟
اینم بگم که من تایپک های مشابه رو دیدم اما راضی نشدم

tux-world
جمعه 10 مرداد 1393, 23:53 عصر
شما اگه مباحث اینترفیس رو تو اشیا یاد بگیرید میتونید توابعی رو بدون بدنه تعریف و از اون استفاده کنید در جاهای دیگه که مستلزم پیاده سازی هستن و یا اینکه شما میتونید یه تابع کلاس رو باز نویسی کنید یا توسعه بدید که بهش میگن Override کردن. منظور اینه که ممکنه کاری که اون تابع برای تعریفی که شده تو جای دیگه ای از کلاس به کار نیاد و یا اینکه ناقص باشه به این شکل توسعه میدنش.
جاوا هم تقریبا به شکل سی رفتار میکنه. تو جاوا تو هر فایلی شما باید یه کلاس داشته باشید البته حداقلش و بعد این کلاسها داخل کلاسهای دیگه میتونن استفاده بشن ولی با پسوند JAVA ولی در سی شما همین کارا رو داخل یه فایل به اسم هدر انجام میدین یعنی چیزهایی که مثل کلاس لازم دارید رو توش پیاده سازی و ازشون هر جایی خواستید بهتره میگیرید. تفاوت آنچنانی ندارن.
البته جاوا تو زمینه شی گرایی یه خورده بدریخت عمل کرده ولی رفتارش مثل پدرش یعنی سی هست

کامبیز اسدزاده
شنبه 11 مرداد 1393, 10:46 صبح
سلام

در ادامه توضیحات دوست عزیز tux-world منم تکمیلترش کنم... شاید راضی بشید.

ببینید در C++‎‎‎ به دلیل اینکه مقدار و نوع کد نویسی بسیار بیشتر و پیچیده تر از هر زبان شئی گرایی دیگری هستش اومدن یه امکانی گذاشتن به نام separating که واجب نیست از این روش استفاده کردن ولی بسیار بهینه میکنه کد نویسی و خوانایی و همچنین دسترسی های سریع و تعاریف قابل استفاده رو در سرتاسر کلاس ها و توابع دیگر.

حالا این به چه شیوه عمل میکنه...

فرض کنید من یک تابعی تعریف میکنم که وقتی صداش میزنم یک چیزی برام چاپ کنه به صورت زیر پیاده سازیش میکنم.

در فایل CPP به صورت زیر :


void _i_PRINT_()
{
std::cout << "Welcome to C++‎‎‎ 11":
}


خب حالا من این تابع رو در داخل همین فایل میتونم فراخوانیش کنم و ازش استفاده کنم البته تحت شرایط public و یا private میتونم سطح دسترسی رو بهش تعریف کنم که در توابع دیگه نیز قابل دسترس باشه یا نباشه.

حالا این روش یه چندتا ایرادی هم داره....


من الان بخوام از این تابع یعنی _i_PRINT_در کلاس دیگه ای استفاده کنم یا در فایل دیگه ای که کاملا خارج از فایل جاری هستش ازش استفاده کنم نخواهم توانست مگر اینکه تابع رو مجددا و دوباره بازنویسی کنم در قسمتی که لازمه فراخوانی بشه...
شیوه نوشتاری این تابع در داخل فایل من به صورت یکجا هست و کاملا مرتبط هستش با فایل و یا کلاس جاری من.


خب در این حالت برای اصلاح باید چکار کنم برای اینکه بتونم سریع و با یک بار نوشتن این تابع در هر کلاس و هر تابع دیگر و در هر فایلی در سرتاسر پروژه بتونم فراخوانیش کنم...

میام در یک فایل .h من بدنه تابع رو پیاده سازی میکنم به صورت زیر :


class TEST
{


public:
void _i_PRINT_();


};



فرض کنید فایلی دارم به نام header.h همین رو در داخل این فایل نوشتم و موجب شده من بدنه اصلی تابع رو تعریف کنم بدون اینکه بدنه فرایند اجرایی تعریف بشه.
یعنی پی ریزی یک تابع صورت گرفته و تنها باید بدنه اجرائی رو پیاده سازی کنم.

در یک فایل مشابه با پسوند .cpp میام عملیاتی رو که قرار انجام بگیره پیاده سازی میکنم به صورت زیر :


#include <iostream>
#include "Header.h"


void TEST::_i_PRINT_()
{

std::cout << "Welcome to C++‎‎‎ 11";




};




خب حالا بعد از تعریف تابع من در خارج از فایل جاری یعنی فایل اجرائی من که هدفم در داخل اون هستش میتونم تابع رو فراخوانی کنم به صورت زیر در فایل main.cpp بدون بازنویسی مجدد تابع فقط میتونم با کمترین کد نویسی یعنی فراخوانی تابع همراه از طرف کلاس از تابع _i_PRINT_ استفاده کنم به صورت زیر :


#include <iostream>
#include "Header.h"


int main()


{


TEST * iTEST = new TEST();
iTEST->_i_PRINT_();


getchar();


return 0;


}




البته به یک نکته ای اشاره کنم که در C++‎ هیچ محدودیتی در رابطه با این که بدنه تابع من حتما باید اول پیاده سازی بشه یا نشه نداریم فقط این روش و اصولی هستش که به شما اجازه میده در صورتی که پروژه عظیمی دارید بتونید تنها با یافتن تابع یا کلاس مورد نظر مشکلش رو رفع کنید در صورتی که از این روش استفاده نکنید باید دونه دونه بشینید توابع یا کلاس هایی که قراره تغییرات در اونها ایجاد بشه رو بررسی کنید.

اگه متوجه نشید دیگه من حرفی ندارم از این واضحتر چیزی به ذهنم نرسید :لبخند:

tux-world
شنبه 11 مرداد 1393, 13:49 عصر
توضیحات تکمیلی بسیار جالبی دادید. یه سوالی به ذهنم رسید اینکه ما تو php اگه بخواییم به اعضای یک کلاس بدون ایجاد نمونه جدید میتونیم با :: دسترسی داشته باشیم به صورت استاتیک تعریف میکنیم یا اینکه یکی از متدهای اون کلاس رو به عنوان سازنده به کانستراکتور ارجاع بدیم. ولی در مثال شما:


void TEST::_i_PRINT_()

به صورت پابلیک تعریف شده و این تو php نمیشه. و یه مورد دیگه در مورد این دسترسی به کلاسها. تو جاوا شما میتونید یه بسته تعریف کنید کلاسهای اون بسته به راحتی همدیگه رو میشناسن حتی اگه تو دایرکتوی های متفاوتی باشن.در صورتی که یه فایل h. داشته باشیم و این تو روت باشه فایلهایی که داخل دایرکتوری های اون پوشه باشن دسترسی چطور میشه؟

تو php ما میاییم آغازگر یه کلاس کلاسهای دیگه رو include میکنیم که این باعث میشه یه کپی از اونها رو تو حافظه داشته باشیم. و هر جا به راحتی میتونیم استفاده کنیم و یا اینکه اون ها رو تو include آدرس میدیم که میگیم فایل کجاست.

کامبیز اسدزاده
شنبه 11 مرداد 1393, 14:04 عصر
توضیحات تکمیلی بسیار جالبی دادید. یه سوالی به ذهنم رسید اینکه ما تو php اگه بخواییم به اعضای یک کلاس بدون ایجاد نمونه جدید میتونیم با :: دسترسی داشته باشیم به صورت استاتیک تعریف میکنیم یا اینکه یکی از متدهای اون کلاس رو به عنوان سازنده به کانستراکتور ارجاع بدیم. ولی در مثال شما:


void TEST::_i_PRINT_()

به صورت پابلیک تعریف شده و این تو php نمیشه. و یه مورد دیگه در مورد این دسترسی به کلاسها. تو جاوا شما میتونید یه بسته تعریف کنید کلاسهای اون بسته به راحتی همدیگه رو میشناسن حتی اگه تو دایرکتوی های متفاوتی باشن.در صورتی که یه فایل h. داشته باشیم و این تو روت باشه فایلهایی که داخل دایرکتوری های اون پوشه باشن دسترسی چطور میشه؟

تو php ما میاییم آغازگر یه کلاس کلاسهای دیگه رو include میکنیم که این باعث میشه یه کپی از اونها رو تو حافظه داشته باشیم. و هر جا به راحتی میتونیم استفاده کنیم و یا اینکه اون ها رو تو include آدرس میدیم که میگیم فایل کجاست.

دقیقا در C++‎‎‎‎‎‎‎‎‎ هم امکان پذیره... کافیه همانند نمونه PHP تابع رو از نوع استاتیک در نظر بگیرید به این صورت :

روشی که میتونید بدون ایجاد نمونه جدید ازش استفاده کنید به صورت زیر هستش :


فایل هدر : .h

در این قسمت تابع رو از نوع static تعریف میکنم...


class TEST
{


public:
static void _i_PRINT_();


};


فایل سورس .cpp


#include <iostream>
#include "Header.h"


void TEST::_i_PRINT_()
{

std::cout << "Welcome to C++‎‎‎‎‎‎‎‎‎ 11";




};




و فایل اجرایی من که در اینجا بدون ایجاد نمونه جدید ازش فراخوانی کردم.


#include "Header.h"


int main()


{


TEST::_i_PRINT_();
return 0;


}

tux-world
شنبه 11 مرداد 1393, 15:36 عصر
خوب در PHP نیازی نیست ما حتما تابع رو به صورت استاتیک تعریف کنیم. میتونیم یکی از متدهاشو به عنوان یه سازنده به کانسترکتور ارجاع بدیم و تمام.