PDA

View Full Version : مبتدی: CLASS+PUBLIC



mado1362
سه شنبه 18 مهر 1396, 18:12 عصر
دوستان مفهوم این کد چیست؟مفهوم کلاس رو متوجه شدم اما این رو نه.
template<class TFsmc>
class Fsmc16BitAccessMode : public FSMC_NORSRAMInitTypeDef {


protected:
volatile uint16_t *_dataAddress;
volatile uint16_t *_registerAddress;
GpioPinRef _resetPin;


public:
Fsmc16BitAccessMode(const Fsmc8080LcdTiming& timing,uint16_t registerAddressLine,const GpioPinRef& resetPin);
Fsmc16BitAccessMode(const Fsmc8080LcdTiming& readTiming,const Fsmc8080LcdTiming& writeTiming,uint16_t registerAddressLine,const GpioPinRef& resetPin);


void initialise(const Fsmc8080LcdTiming& readTiming,const Fsmc8080LcdTiming& writeTiming,uint16_t registerAddressLine);
void initialiseTiming(const Fsmc8080LcdTiming& readTiming,const Fsmc8080LcdTiming& writeTiming);


void enable(bool enable);
void reset();


void writeCommand(uint16_t command) const;
void writeCommand(uint16_t command,uint16_t parameter) const;
void writeData(uint16_t value) const;
void writeDataAgain(uint16_t value) const;
void writeMultiData(uint32_t howMuch,uint16_t value) const;
uint16_t readData() const;


volatile uint16_t *getDataAddress() const;
void rawTransfer(const void *buffer,uint32_t numWords) const;
static void getDmaTransferSizes(uint32_t& peripheralsize,uint32_t& memsize);
};

hamedBB
سه شنبه 18 مهر 1396, 19:01 عصر
سلام. مفهوم این کلاس وابسته به یک پروژه کامل هست و صرفا با یک فایل هدر نمیشه مفهومش رو گفت.
ولی اگر سوالتون درباره کلیدواژه های استفاده شده در این فایل هست من به صورت مختصر توضیحی براتون میگم :
template<class name>
این خط به این معناست که این کلاس یه کلاس template هست. یعنی تا زمانی که instance ای از این کلاس ساخته نشده کدی تولید نخواهد شد و زمانی که ازش instance میخواهید بسازید باید یک دیتا تایپ خاص بهش پاس بدید و عملکرد این کلاس وابسته به اون دیتا تایپ متفاوت خواهد بود. برای درک بهتر این موضوع پیشنهاد میکنم درباره ی template programming و به صورت جزئی template class بیشتر مطالعه کنید.
class Fsmc16BitAccessMode : public FSMC_NORSRAMInitTypeDef
این خط صرفا نام کلاس هست و اینکه این کلاس به صورت public از کلاس FSMC_NORSRAMInitTypeDef ارث بری میکند. اگر با مفهوم ارث بری یا انواع ارث بری آشنایی ندارید پیشنهاد میکنم دربارشون مطالعه کنید یا پست جداگانه ای ایجاد کنید، در متن این پاسخ نمی تونم همش رو توضیح بدم.
protected:
از این خط به بعد تا جایی که نوشته شده public: تمام member dataهای گفته شده protected هستند. این به این معنی هست که فقط توسط خود کلاس و کلاس هایی که از این کلاس ارثبری کرده اند و توابع دوست قابل دستیابی هست.
volatile
این کلید واژه جلوی کامپایلر رو برای اعمال هرگونه بهینه سازی روی این متغییر میگیره. برای درک بهتر این موضوع باید مواردی که کامپایلر سر خود بهینه سازی میکنه رو مطالعه کنید.
const type &parameter
همونطور که در توابع public این کلاس مشاهده میکنید اکثر پارامتر های این توابع فرمت ذکر شده رو دارند. این باعث میشه این متد call by reference بشه. این شکل پاس دادن پارامتر ها معمولا برای user defined data types یا همون دیتا تایپ هایی که کاربر معرفی میکنه (کلاس ها و استراکچرها) استفاده میشه. چون در این مدل دیتا تایپ ها زمان سربار کپی زیاد هست و زمان de-reference کردن به نسبت این زمان کپی ناچیز هست و در این مواقع بهتر هست از این روش استفاده کنید. عبارت const هم به این معناست که این پارامتر توسط تابع تغییر نخواهد کرد.
type functionName(parameters) const
اگر به چند تابع پایینتر نگاه کنید کلمه const رو پایان اون ها میبینید. این کلیدواژه به این معناست که این تابع چیزی از خود کلاس (به طور کلی instance ای که ساختید) رو تغییر نخواهد داد.
static type functionName(parameters)
اگر به آخرین متد این کلاس دقت کنید قبل از اون کلید واژه static اومده. این به این معناست که اجرای این تابع وابسه به ساخت هیچ instance ای از این کلاس نیست و شما میتونید صرفا با فرمت ClassName::functionName(parameters) این تابع رو صدا کنید و از سرویسش استفاده کنید.

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

mado1362
چهارشنبه 19 مهر 1396, 11:41 صبح
ممنون.:تشویق:

mado1362
چهارشنبه 19 مهر 1396, 18:57 عصر
سلام.این قسمت رو متوجه نشدم.منظورم دو نقطه است.
PushButton::PushButton(const GpioPinRef& pin,bool pressedState)
: _pin(pin) {
146690

hamedBB
پنج شنبه 20 مهر 1396, 11:29 صبح
سلام مجدد.
کدوم دو نقطه منظورتونه؟ اون دوتایی اولی یا اون تکی دومیه؟ من هردو رو توضیح میدم.
اگر اون دوتا دو نقطه رو می فرمایید، بهش میگن Scope Resolution Operator. این عملگر هر چیزی در سمت چپش بیاد scope هست و هرچیزی در سمت راستش بیاد یک متد یا دیتای مربوط به اون scope هست.

حالا یه اسکپ چی میتونه باشه؟ scope میتونه یک namespace یا class یا structure یا enum باشه. البته scope میتونه هرچیزی بین {} هم باشه ولی اینجا منظور scope های اسم دار هست.

کدی که فرستادید مربوط به class scope میشه و PushButton یک کلاس هست. حالا اینکه هیچ return type یا مقدار بازگشتی ای نداره و اسم متدی که بعد از دونقطه اومده با اسم کلاس یکی هست نشون میده که این متد constructor کلاس PushButton هست.

constructor چی هست؟ constructor متدی هست که هنگام ساخت instance از کلاس به صورت خودکار صدا زده میشه. حالا این که کدوم constructor صدا زده میشه وابسته به این هست که شما با چه پارامتر هایی اون instance رو بسازید.

یک سری constructorها اگر شما تعریفشون نکنید خود compiler براتون تعریفشون میکنه مثل default constructor یا copy constructor یا move constructor ولی تو این کدی که شما فرستادی نویسنده ترجیح داده بنا به نیازش constructor خودش رو بنویسه که دوتا پارامتر میگیره.


حالا اگر اون دو نقطه تکی دومیه رو میگید اون به این معناست که هر متدی بعد از اون دونقطه بیاد در زمان ساخت instance صدا زده خواهد شد. یعنی زمانی که شما از کلاس PushButton یک instance بسازید (البته با دو پارامتر مورد نظر یعنی GpioPinRef pin و bool pressedState) بعد از اینکه بدنه constructor اجرا شد تابع _pin(pin) صدا زده خواهد شد. و چیزی که مشخص هست اینه که pin در زمان ساخته شدن PushButton ساخته میشه و بعد به تابع _pin پاس داده میشه.

اگر سوالی بود در خدمتم.
موفق باشید.

mado1362
پنج شنبه 20 مهر 1396, 13:11 عصر
ممنون از جواب شما که کامل بود.
در اینجا برای پیاده سازی تابع
ButtonState getState();
من انتظار دارم اینطور تعریف شود :
PushButton::ButtonState getState() {
اما اینجوری تعریف شده:
PushButton::ButtonState PushButton::getState() {

mado1362
پنج شنبه 20 مهر 1396, 13:27 عصر
و اینکه من namespace رو که فضای نام هست و برای تعریف کلاسهای مشابه کاربرد دارد رو درک کردم.
در اینجا تمام کلاسها رو در
namespace stm32plus {
قرار داده .و در هدر های جدا هر کجا که بخاد کلاس رو تعریف کنه اونو توی
namespace stm32plus {}
قرارداده.
سوال من اینه که آیا از namespace برای همین منظور استفاده شده و نمیتونم غیر از این کلاس رو تعریف کنم؟
و بعد اینکه در هدرهای مختلف کلاس ها رو در namespace جدا گانه نوشته , همه تعریفها در بستر یک namespace است؟

hamedBB
پنج شنبه 20 مهر 1396, 13:36 عصر
نه شما یه چیزی رو در مورد scope resolution متوجه نشدید. ببینید اگه من توی تعریف کلاسم بگم مثلا متد methodName() رو دارم. در بدنه کلاسم وقتی میخوام این تابع رو تعریف کنم فرمتش به شکل زیر هست :

returnType ClassName::methodName(parameters)

این از این. خوب حالا شما اگه دقت کنید میبینید که توی header کلاس pushbutton یک enume وجود داره به اسم ButtonState. خوب این enum تو scope این کلاس هست. حالا مقدار بازگشتی متد getState یک ButtonState هست. پس اگر قرار باشه این سینتکس رو فارسی بخونیم میشه متد getState از کلاس PushButton که مقدار بازگشتی آن ButtonState از کلاس PushButton هست و پارامتر ورودی ای ندارد.

به سودوکدی که بالاتر نوشتم دوباره دقت کنید :
returnType = PushButton::ButtonState
ClassName = PushButton
methodName = getState
parameters = none

اگر توضیح بیشتری نیاز بود در خدمتم.
موفق باشید

hamedBB
پنج شنبه 20 مهر 1396, 13:39 عصر
و اینکه من namespace رو که فضای نام هست و برای تعریف کلاسهای مشابه کاربرد دارد رو درک کردم.
در اینجا تمام کلاسها رو در
namespace stm32plus {
قرار داده .و در هدر های جدا هر کجا که بخاد کلاس رو تعریف کنه اونو توی
namespace stm32plus {}
قرارداده.
سوال من اینه که آیا از namespace برای همین منظور استفاده شده و نمیتونم غیر از این کلاس رو تعریف کنم؟
و بعد اینکه در هدرهای مختلف کلاس ها رو در namespace جدا گانه نوشته , همه تعریفها در بستر یک namespace است؟

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

mado1362
پنج شنبه 20 مهر 1396, 14:17 عصر
ممنون متوجه شدم.
در مورد namespace قسمت دوم سوال منظور اینه که کلاسها رو توی {} قرار میدیم و هدر های بعدی هم به همین صورت و با نام namespace stmplus ,آیا مثل اینه که ما همه را در یکجا namespace stm32plus قرار داده باشیم.

hamedBB
پنج شنبه 20 مهر 1396, 14:23 عصر
متوجه شدم.
بله namespace مشابه دارند پس همشون در یک namespace هستن. همونطور که گفتم بهتر هست کلاس های مرتبط در یک namespace باشند و این کاری هست که نویسنده کد انجام داده.

mado1362
شنبه 22 مهر 1396, 12:04 عصر
این سه نقطه در template<> برای چیست؟
template<uint8_t... TPins >
و بعد چرا در داخل template<> از هیچ اسمی استفاده نشده؟
template<> ExtiInterruptEnabler<17>::FPTR ExtiInterruptEnabler<17>::_forceLinkage=nullptr;

hamedBB
شنبه 22 مهر 1396, 13:07 عصر
به این سه نقطه میگن parameter pack و به این معناست که این template میتونه تعداد نا مشخصی (از 0 تا nتا) uint8_t بگیره.

اینکه چرا داخل <> هیچ پارامتری نیست به این دلیل هست که نویسنده میخواسته این template را specialize کنه. اگر دقت کنید بعد از <> ، ExtiInterruptEnabler<17> اومده. یعنی این template به تایپ int محدود شده.

احساس میکنم اصلا خوب توضیح ندادم این موارد رو ولی به طور کلی توضیح این ها به صورت مختصر و به زبان فارسی کمی سخت هست.
موفق باشید.

mado1362
شنبه 22 مهر 1396, 13:14 عصر
ممنون.من کامل متوجه شدم.من زبان سی رو دو سال هست که دتبال میکنم.وقبل از طرح سوال تقریبا به تمام رفرنسها سر زدم.اما مساله اینجاست که تمام این نکات و ویرایشهای مختلف رو یکجا توضیح ندادند و یا من پیدا نکردم.من به صورت کلی و در قالب استاندارد بیشتر موارد سی پلاس رو سعی کردم یاد بگیرم. اما با یک تغییر کوچک مثل سوالات اخیر , گیج میشوم.

hamedBB
شنبه 22 مهر 1396, 13:24 عصر
ممنون.من کامل متوجه شدم.من زبان سی رو دو سال هست که دتبال میکنم.وقبل از طرح سوال تقریبا به تمام رفرنسها سر زدم.اما مساله اینجاست که تمام این نکات و ویرایشهای مختلف رو یکجا توضیح ندادند و یا من پیدا نکردم.من به صورت کلی و در قالب استاندارد بیشتر موارد سی پلاس رو سعی کردم یاد بگیرم. اما با یک تغییر کوچک مثل سوالات اخیر , گیج میشوم.

من پیشنهاد میکنم کتاب ++effective c رو بخونید. در این کتاب نویسنده گفته باید به زبان c به صورت یک فدرال از زبان ها نگاه کرد. و این فدرال رو به چهار بخش C و ++C و Template و STL تقسیم کرده که هرکدوم رو به اختصار توضیح داده.
مسلما ++C زبانی هست که از سینتکس ها و کاربرداهای بسیار متفاوتی تشکیل شده و این تقسیم بندی باعث میشه ذهن شما متمرکز تر بشه و بدونید در هر جای این زبان بزرگ و قدرمتند با کدام بخش طرف هستید و اگر در بخشی ضعیف هستد بتونید اون رو تقویت کنید.
برای مثال شما در پروژه فعلیتون بیشتر درگیریتون سمت template هست. برای یادگیری بهتر این بخش من پیشنهاد میکنم کتاب C Template Complete Guide (ترجیحا ویرایش دوم) رو بخونید. کتاب بزرگی هست ولی وقتی تمومش کنید میتونید خودتون رو در این بخش کاملا ماهر بدونید.

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

موفق باشید.