رفتن به مطلب
جامعه‌ی برنامه‌نویسان مُدرن ایران
  • 0
فرهاد شیری

ایجاد property با استفاده از انواع داده استاندارد


سوال

 معمولا یکی از چالش های برنامه نویسی شی گراء که همواره بر سر راه برنامه نویسان وجود دارد، Map شدن دیتاهای موجود در بانک های اطلاعاتی در کلاس های model می باشد. 

به این ترتیب که بتوان داده ها را در فیلدهایی که در کلاسهای مدل که تعریف شده اند را به این داده ها متصل نمود به همین علت بعد از این Map شدن داده ها باید متدهایی جهت یکپارچه سازی داده ها در این کلاسهای model تعریف نمود تا هم بتوان مقادیر این داده ها را بازیابی کرد وهم بتوان به راحتی این داده ها را به روز رسانی نمود.

در صورتی که تجربه کار با entity framework ها را داشته باشید، قطعا متوجه شده اید که وقتی داده ها را به Property کلاسهای مدل Map میکنیم به راحتی با خود همین خصیصه های تعریف شده هم عملیات بازیابی را انجام می دهیم و هم به راحتی مقدار های جدید فیلدهای مرتبط به خصیصه راهم به روز رسانی می نماییم، که با این کارهم بازدهی برنامه بالاتر خواهد بود وهم از نوشتن متدهای پردردسر هم راحت میشویم.

با ذکر این مقدمه قصد دارم کلاسی را خدمتتان معرفی کنم که جهت تعریف property ها استفاده می شود، البته استفاده از خصیصه ها در entity framework یکی از کاربرد property می باشد.

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

#ifndef PROPERTY_H_
#define PROPERTY_H_

#include "MyException.h"
#include "typeinfo"

template<typename Tp>
struct CProperty{
	typedef Tp property_type;

private:
	inline void setLength(property_type& rhs) throw(MyException){
       	const_cast<size_t&> (length)  = (reinterpret_cast<std::string*>(&rhs))->length();
	}
	const property_type m_property;
public:
	/*Preorder:
	 * default constructor is commented! because if
	 * uncommented and create new object from this and no passed
	 * default value property and when compile the program compiler
	 * no sending error but show error in linker program.
	 */
	//CProperty();
	//Preorder: copy constructor
	CProperty(const CProperty<property_type>& rhs): m_property(rhs.m_property) ,length(0) ,data(get()) {}
	//Preorder: copy operator
	const CProperty& operator=(const CProperty<property_type>& rhs){
		const_cast<property_type&>(m_property) = rhs.m_property;
        return *this;
	}
	/*Preorder:
	 * when create new property must pass the default value of
	 * property!
	 */
    explicit CProperty(const property_type& rhs) : m_property(rhs) ,length(0) ,data(get()) {
    	operator =(rhs);
    }
	//PreOrder: setter method
	inline void operator=(const property_type& rhs) throw(MyException){
		const_cast<property_type&>(m_property) = rhs;
		if(strcmp(typeid(property_type).name(),"Ss") == 0)
			setLength(const_cast<property_type&>(rhs));
	}
    //override comapre method in string class
	inline bool operator==(const property_type& rhs) throw(MyException){
		return get().compare(rhs) == 0;
	}
	inline bool operator==(const property_type& rhs) const throw(MyException){
		return get().compare(rhs) == 0;
	}
	operator Tp() {
		return m_property;
	}
	operator Tp() const {
		return m_property;
	}
    //get the value property
	property_type& get(){
	   return *(reinterpret_cast<property_type*>(&const_cast<property_type&>(m_property)));
	}
	const property_type& get() const {
	   return *(reinterpret_cast<property_type*>(&const_cast<property_type&>(m_property)));
	}
	const size_t length;
	const property_type data;
};

typedef struct CProperty<bool> Bool;
typedef struct CProperty<int> Int;
typedef struct CProperty<std::string> String;

#endif /* PROPERTY_H_ */

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

/*define and set new string property in direct mode*/
const String myStr1("test1");
String myStr2("test1");
/*change property value.l*/
//myStr1 = "change test1";
std::cout << "My String 1 property is:(" << myStr1.data << ") and this length is:(" << myStr1.length << ") " << '\n';
std::cout << "My String 2 property is:(" << (string)myStr2 << ") and this length is:(" << myStr2.length << ") " << '\n';
/*comapre two strings*/
if(myStr2 == myStr1)
   std::cout << "myStr2 and myStr1 is equal!" << '\n';
else
   std::cout << "myStr2 and myStr1 is not equal!" << '\n';

/*define boolean property*/
Bool bol(false);
std::cout << bol << '\n';
Bool bol2(false);
std::cout << bol << '\n';
if((bool)bol2 == (bool)bol)
   std::cout << "bol2 and bol is equal!" << '\n';
else
   std::cout << "bol2 and bol is not equal!" << '\n';

/*define int property*/
Int myInt(10);
//myInt = 20; //change property

در صورتی که ابهام وجود داشت بفرمایید.

و اگر هم پیشنهادی و یا انتقادی داشته باشید، خوشحال خواهم شد مطرح کنید.

موفق باشید

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

2 پاسخ به این سوال تا کنون داده شده است

پست های پیشنهاد شده

  • 0

@فرهاد شیری درود بر شما؛

بابت مبتدی بودن سوأل عذرخواهی می‌کنم؛ ابهام‌هایی در قسمت‌هایی از کد برایم وجود داشت که درست متوجه نشدم.

در این قسمت :

explicit CProperty(const property_type& rhs) : m_property(rhs) ,length(0) ,data(get()) {
    operator =(rhs);
}

هدف‌‍تان از ;operator =(rhs) چه بوده ؟ مگر عملگر = نیاز به دو عملوند ندارد ؟ چگونه به یک‌باره فراخوانی شده ؟ و چه نیازی بوده ؟

 

در قسمت دیگر:

property_type& get(){
	   return *(reinterpret_cast<property_type*>(&const_cast<property_type&>(m_property)));
}

متوجه هدفتان از این تبدیل‌های پیاپی نشدم.

با تشکر از شما.

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر
  • 0
در 9 ساعت قبل، قاسم رمضانی منش گفته است :

بابت مبتدی بودن سوأل عذرخواهی می‌کنم؛ ابهام‌هایی در قسمت‌هایی از کد برایم وجود داشت که درست متوجه نشدم.

 

جناب رمضانی منش به نظرم سوال شما اصلا مبتدی نیست بلکه دقت نظر بالای شما را می رساند!

در 9 ساعت قبل، قاسم رمضانی منش گفته است :

explicit CProperty(const property_type& rhs) : m_property(rhs) ,length(0) ,data(get()) {
    operator =(rhs);
}

 

در این کلاس عملگر (=) را مجدد بارگذاری کردم، که باعث می شود در زمان تعریف یک property مقداردهی اولیه را انجام دهد و در صورتی که رشته باشد طول این رشته نیز مقدار دهی می شود. بنابراین در سازنده کلاس هم باید این منطق تکرار شود و به علت اینکه از کد تکراری استفاده نشود عمگر (=) را به این صورت فراخوانی شده است. فراخوانی متدهای عضو کلاس از داخل متدهای عضو که برای فراخوانی عملگرهای بارگذاری شده به این صورت ((-)=operator) فراخوانی می شود.

که می توان به این شکل هم نوشت ...

explicit CProperty(const property_type& rhs) : m_property(rhs) ,length(0) ,data(get()) {
    this->operator =(rhs);
}
OR
explicit CProperty(const property_type& rhs) : m_property(rhs) ,length(0) ,data(get()) {
    ::operator =(rhs);
}  

 

در 9 ساعت قبل، قاسم رمضانی منش گفته است :

property_type& get(){
	   return *(reinterpret_cast<property_type*>(&const_cast<property_type&>(m_property)));
}

 

و دراین قسمت هم اگر در زمان تعریف یک property یک رشته داشته باشیم، جهت اینکه در زمان اجرا به مقدار کلاس string صحیح اشاره کنم به این صورت تبدیل کرده ام.

بنابراین به علت اینکه مقدار m_property یک عضو const تعریف شده است، لذا با استفاده از const_cast رفرنس متغیر عضو m_property را از حالت const خارج میکنم و در زمان اجرا به یک اشاره گر *string با استفاده از عملگر reinterpret_cast تبدیل میکنم و در نهایت هم که مقدار اشاره گر را دی رفرنس میکنم و یک رفرنس از کلاس property که به string تبدیل شده را در سازنده به یک متغیر عضو به نام data منتقل میکنم.

و البته به این صورت هم می شد نوشت...

property_type& get(){
	   return *(reinterpret_cast<property_type*>(&const_cast<property_type&>(m_property)));
}
OR
property_type& get(){
	   return *((property_type*)&const_cast<property_type&>(m_property));
}         

بازهم تشکر میکنم از حسن توجه شما دوست گرامی.

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

مهمان
پاسخ به این سوال ...

×   شما در حال چسباندن محتوایی با قالب بندی هستید.   حذف قالب بندی

  تنها استفاده از ۷۵ اموجی مجاز می باشد.

×   لینک شما به صورت اتوماتیک جای گذاری شد.   نمایش به عنوان یک لینک به جای

×   محتوای قبلی شما بازگردانی شد.   پاک کردن محتوای ویرایشگر

×   شما مستقیما نمی توانید تصویر خود را قرار دهید. یا آن را اینجا بارگذاری کنید یا از یک URL قرار دهید.


  • کاربران آنلاین در این صفحه   0 کاربر

    هیچ کاربر عضوی،در حال مشاهده این صفحه نیست.

×
×
  • جدید...