نمایش نتایج 1 تا 20 از 20

نام تاپیک: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

  1. #1

    آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    باسلام
    یک از مباحث عمیق و پرچالش در برنامه نویسی شی گرایی پلی مورفیسم(چند ریختی) هست که در زبان ++C از سایر زبانها کمی پیچیده تر هست.
    سعی بر این هست که مطالبی که در این مبحث می توان بیان کرد که بیشترین کارآیی را در زمان برنامه نویسی دارند را بیان کنیم.

    پاک کردن نوع در زمان اجرا Type Erasure
    - مخفی کردن جزئیات پیاده سازی.
    - انعطاف پذیری بیشتر در طراحی
    - هزینه پیاده سازی با هزینه پیاده سازی زمان اجرا همراه است.

    struct Base{};
    struct Derived : Base {};

    using namespace std;
    int main(){
    unique_ptr<Base> sp = make_unique<Derived>();
    }
    آخرین ویرایش به وسیله farhad_shiri_ex : دوشنبه 31 اردیبهشت 1397 در 12:48 عصر

  2. #2

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    - زمان طراحی کلاس Base حتما مخرب باید به صورت مجازی تعریف شود.
    - و زمانی که در کلاس Base از مخرب مجازی استفاده کردید بهتر دیگر اشیا اختصاصی کلاس را هم تعریف کنید.
    مثل سازنده کپی و سازنده پیش فرض و سازنده انتقال و سربارگذاری عملگر =

    struct Base{
    Base() = default ;
    Base(const Base&) = default ;
    Base(Base&&) = default ;
    virtual ~Base() = default ;
    Base& oprator= (const Base&) = default ;
    Base& oprator= (Base&&) = default ;
    };
    آخرین ویرایش به وسیله farhad_shiri_ex : دوشنبه 31 اردیبهشت 1397 در 12:52 عصر

  3. #3

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    استفاده از سازنده استاتیک و اتوماتیک کردن اجرای مخرب شی توسط اشاره گرهای هوشمند و اجرای رفرنس فانکشن مخرب شی توسط decltype.
    struct myTestBase {
    static void destory(myTestBase* my){
    delete my ;
    }
    static unique_ptr<myTestBase , decltype(&destory)> create(int a , string& name){
    return unique_ptr<myTestBase , decltype(&destory)>(new myTestBase(a,name) , &destory);
    }
    int a;
    string name;
    private:
    myTestBase() = default;
    myTestBase(int k ,const string& n) : a(k) ,name(n){}
    ~myTestBase(){
    cout << "dctor is run!" << endl;
    }
    };};
    آخرین ویرایش به وسیله farhad_shiri_ex : دوشنبه 31 اردیبهشت 1397 در 12:53 عصر

  4. #4

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    استفاده از الگوی MixIn and CRTP(Curiously Recurring Template Pattern) برای استفاده بهینه از کلاسهای template و up casting در زمان اجرا.
    و اجرای رفرنس متد در کلاس پایه با استفاده از دستور using بدون استفاده از مجازی کردن متد کلاس پایه جایگزین مناسب برای متد های مجازی Reference Method
    کاری که در زبان برنامه نویسی جاوا یک آرزو دست نیافتنی بوده و هست.!!

    template<typename T> struct MixIn {
    auto sum() {
    return static_cast<T*>(this)->lhs +
    static_cast<T*>(this)->rhs ;
    }
    };
    struct Integer : MixIn<Integer> {
    int lhs =0 ;
    int rhs =0 ;
    using MixIn<Integer>::sum; // method refernce
    };

    struct Double : MixIn<Double> {
    double lhs =0.0 ;
    double rhs =0.0 ;
    using MixIn<Double>::sum; // method refernce
    };

    int main(){
    Integer sInt ;
    sInt.lhs = 10 ;
    sInt.rhs = 20 ;
    cout << "sum int is :" << (sInt.sum()) << endl ;

    Double sDubl ;
    sDubl.lhs = 10.8 ;
    sDubl.rhs = 20.3 ;
    cout << "sum double is :" << (sDubl.sum()) << endl ;
    }

    ادامه خواهد داشت ...
    سوالی بود لطفا همین جا اطلاع دهید.!
    آخرین ویرایش به وسیله farhad_shiri_ex : دوشنبه 31 اردیبهشت 1397 در 12:48 عصر

  5. #5
    کاربر دائمی آواتار vahid-p
    تاریخ عضویت
    آذر 1391
    محل زندگی
    تهران
    پست
    1,140

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    در مورد پست شماره #3 میخواستم بدونم عملکرد unique_ptr و decltype چی هست و هر کدوم چه وظیفه ای رو دارن؟
    مثلا من از یه اسکوپ خارج بشم چطور متوجه میشه و اون شی رو delete میکنه؟ ممکنه حالتی پیش بیاد که memory leak پیش بیاد با این روش؟
    یعنی میتونیم بگیم جایگزین garbage collector در جاوا میتونه باشه؟ اگر فرضا داخل آبجکت ساخته شده از این کلاس به نام x مثلا یک آبجکتی باشه به نام y (یعنی y درون x قرار داره) و یه آبجکت دیگه به نام z به آبجکت y اشاره کنه، با مخرب اتوماتیک x آیا اون آبجکت درونی (y) حذف میشه یا رفرنس هاش شمرده میشن؟

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

    با تشکر

  6. #6

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    میخواستم بدونم عملکرد unique_ptr و decltype چی هست و هر کدوم چه وظیفه ای رو دارن؟
    unique_ptr یک اشاره گر هوشمند هست. اشاره گرهای هوشمند به گونه ای طراحی شده اند که از لحاظ حافظه و عملکرد به همان اندازه کارآمد باشند.
    واز اونجا که یکتا هستند نمی تونید کپی ازشون بگیرید فقط می تونید به یک اشاره گر هوشمند دیگه منتقل کنید که در اونصورت اشاره گر اصلی reset میشه.
    به عنوان مثال، تنها عضو داده در unique_ptr، نشانگر خام محصور شده در ویلدکاردها است. به این معنی است که unique_ptr دقیقا به همون اندازه اشاره گرخام، چهار بایت یا هشت بایت است.
    پس در جمع بندی داریم ....
    - unique_ptr اشاره گر آن را به اشتراک نمی گذارد.
    - نمیتواند به یک unique_ptr دیگر از طریق مقدار به یک تابع منتقل شود.
    - در هر الگوریتم STL (Standard Template Library) که نیاز به کپی هایی دارد، مورد استفاده قرار میگیرد.
    - unique_ptr تنها می تواند منتقل شود این به این معنی است که مالکیت منابع حافظه به unique_ptr منتقل شده است و unique_ptr اصلی دیگر آن را ندارد.
    از اونجایی که مالکیت چندگانه منطق برنامه را دچار پیچیدگی می کنه بنابراین هنگامی که نیاز به اشاره گر برای یک شی ساده ++C دارید، از unique_ptr استفاده کنید، و هنگام ساخت یک unique_ptr، از تابع helper make_unique استفاده کنید.

    مثلا من از یه اسکوپ خارج بشم چطور متوجه میشه و اون شی رو delete میکنه؟ ممکنه حالتی پیش بیاد که memory leak پیش بیاد با این روش؟
    همانطور که در مثال زیر نشان داده شده، نشانگر هوشمند، یک الگوی کلاس Template Class است که شما در پشته آن را اعلام می کنید و با استفاده از نشانگر خام که به کلاس person اشاره داره مقدار اولیه را تعیین می کنید.یعنی اشاره گر هوشمند مسئول حذف حافظه اشاره گر خام است. مخرب اشاره گر هوشمند شامل فراخوانی برای حذف است. زمانی که نشانگر هوشمند از محدوده خارج می شود، مخرب آن فراخوانی می شود، حتی اگر یک استثنا تولید بشه.

    void UseRawPointer()
    {
    // Declare a raw pointer on heap -- not recommended.
    Person* pPerson = new Person(L"Farhad", L"Shiri");

    // Use pPerson pointer...

    // Don't forget to delete!
    delete pPerson;
    }


    void UseSmartPointer()
    {
    // Declare a smart pointer on stack and pass it the raw pointer.
    unique_ptr<Person> spPerson(new Person(L"Farhad", L"Shiri"));

    // Use spPerson smart pointer...
    string s = spPerson2->name;
    //...

    } // spPerson is deleted automatically here.


    یعنی میتونیم بگیم جایگزین garbage collector در جاوا میتونه باشه؟
    نشانگر هوشمند ++C شبیه ساختن شی در زبان هایی مانند #C است. شی را ایجاد می کنید و سپس سیستم اون به موقع حذف می کنه.
    تفاوت در این است که هیچ جمع کننده زباله جداگانه در پس زمینه اجرا نمی شود؛ حافظه از طریق قوانین محدوده ++C استاندارد مدیریت می شود تا محیط کاری سریع تر و کارآمدتر باشد.

    اگر فرضا داخل آبجکت ساخته شده از این کلاس به نام x مثلا یک آبجکتی باشه به نام y (یعنی y درون x قرار داره) و یه آبجکت دیگه به نام z به آبجکت y اشاره کنه، با مخرب اتوماتیک x آیا اون آبجکت درونی (y) حذف میشه یا رفرنس هاش شمرده میشن؟

    ضمنا آیا لازمه کارکرد صحیح، این هست که کلاس هایی که در این کلاس مورد استفاده قرار گرفتن هم از مخرب اتوماتیک داشته باشن؟
    و تفکر تعریف کلاس پست شماره 3 این هست که ما با تعریف سازنده و مخرب کلاس به صورت private از کلاس نتونیم خارج از متد فاکتوری create یک شی جدید ایجاد کنیم.
    همچنین با استفاده از دستور decltype دیگه نیازی به تعریف مجازی مخرب نخواهیم داشت پس با تعریف کلاس به این شکل نه تنها از سازنده استاتیک با اشاره گر هوشمند استفاده کردیم بلکه با روش decltype هر کلاسی هم که از کلاس ارث بری داشته باشه کار مخرب مجازی را پیاده سازی کردیم.
    دستور deltype هم یک type از نوع پارامتر خودش بر میگردونه که در کلاس فوق یک رفرنس از متد ارجاعی را برمیگردونه یه چیزی شبیه به delegate در زبان #c.
    چون وقتی از مخرب های هوشمند استفاده میکنیم به نسبت مجازی کردن مخرب کلاس در مصرف حافظه به طرز چشمگیری صرفه جویی کردیم.
    به طور مثال در کد زیر که برای سورت وکتور برای یکی از تاپیکها در همین تالار نوشته بودم توجه کنید که چطور از این تکنیک استفاده شده برای بهینه شدن الگوریتم.
    struct MyStructs
    {
    static void destory(MyStructs* my){
    delete my ;
    }
    static unique_ptr<MyStructs , decltype(&destory)> create(int k, string& s){
    return unique_ptr<MyStructs , decltype(&destory)>(new MyStructs(k,s) , &destory);
    }

    int key;
    string stringValue;
    MyStructs(int k, const string& s) : key(k), stringValue(s) {}
    private :
    MyStructs() = default;
    ~MyStructs(){}

    };

    void customSort(vector<MyStructs*>& vect){
    void swapData(const MyStructs* const, MyStructs* const,MyStructs* const);
    void swapData2(const MyStructs& , MyStructs* const,MyStructs* const);
    for(vector<MyStructs*>::const_iterator ci=vect.cbegin(); ci !=vect.cend(); ++ci){
    for(vector<MyStructs*>::const_iterator ji=ci; ji !=vect.cend(); ++ji){
    if(vect.size()>0 && (*ji)->stringValue.compare((*ci)->stringValue) < 0){
    auto tmp = MyStructs::create((*ci)->stringValue.size(),(*ci)->stringValue);
    /* Pass raw pointer to a method can be pointer and value constnt
    is thread safe method*/
    swapData(tmp.get(),*ci,*ji);
    /* Pass a reference to a method can be value constnt but can not pointer constnt */
    //swapData2(*tmp.get(),*ci,*ji);
    }
    }
    }
    }

    void swapData(const MyStructs* const tstruc,MyStructs* const ci,MyStructs* const ji){
    ci->stringValue = ji->stringValue;
    ji->stringValue = tstruc->stringValue;
    ci->key = ji->key;
    ji->key = tstruc->key;
    }

    void swapData2(const MyStructs& tstruc,MyStructs* const ci,MyStructs* const ji){
    ci->stringValue = ji->stringValue;
    ji->stringValue = tstruc.stringValue;
    ci->key = ji->key;
    ji->key = tstruc.key;
    }
    آخرین ویرایش به وسیله farhad_shiri_ex : سه شنبه 01 خرداد 1397 در 21:31 عصر

  7. #7

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    برای مواقعی که بخواهید اشاره گر خام را به یک متد ارسال کنید هم بااستفاد از علامت اشاره گر * و هم با استفاده از متد get می تونید از مثال زیر استفاد کنید..

    class LargeObject
    {
    public:
    void DoSomething(){}
    };

    void ProcessLargeObject(const LargeObject& lo){}
    void SmartPointerDemo()
    {
    // Create the object and pass it to a smart pointer
    unique_ptr<LargeObject> pLarge(new LargeObject());

    //Call a method on the object
    pLarge->DoSomething();

    // Pass a reference to a method.
    ProcessLargeObject(*pLarge);

    // Pass a reference to a method by get().
    ProcessLargeObject(*pLarge.get());

    }
    آخرین ویرایش به وسیله farhad_shiri_ex : سه شنبه 01 خرداد 1397 در 20:41 عصر

  8. #8

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

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

    void SmartPointerDemo2()
    {
    // Create the object and pass it to a smart pointer
    unique_ptr<LargeObject> pLarge(new LargeObject());

    //Call a method on the object
    pLarge->DoSomething();

    // Free the memory before we exit function block.
    pLarge.reset();

    // Do some other work...

    }

  9. #9

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    استفاده از declType برای استفاده از داده بازگشتی یک تابع عضو در ساختار بدون attribute .
    decltype هر نوع کلاس T را به یک نوع مرجع تبدیل می کند.
    و امکان استفاده از اعضای عضو در عبارات decltype را بدون نیاز به فراخوانی سازندگان فراهم می کند.

    declval معمولا در قالب هایی استفاده می شود که پارامترهای قالب قابل قبول، هیچ سازنده ای ندارند اما یک تابع عضو دارند که نوع بازگشت آن مورد نیاز است.


    #include <utility>
    #include <iostream>

    struct Default {
    int foo() const { return 1; }
    };

    struct NonDefault
    {
    NonDefault(const NonDefault&)= delete;
    int foo() const { return 1; }
    };

    int main()
    {
    decltype(Default().foo()) n1 = 4; // type of n1 is int
    //decltype(NonDefault().foo()) n2 = n1; // error: no default constructor
    decltype(std::declval<NonDefault>().foo()) n2 = n1; // type of n2 is int
    std::cout << "n1 = " << n1 << '\n'
    << "n2 = " << n2 << '\n';
    }

  10. #10

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    استفاده از نوع any در 17+c برای تعریف یک متغیر با نوع های مختلف و تبدیل نوع امن آن در ضمن اجرا با any_cast و error handler در زمان پرتاب خطا با استفاده از bad_any_cast


    #include <any>
    #include <iostream>

    int main()
    {
    std::cout << std::boolalpha;

    // any type
    std::any a = 1;
    std::cout << a.type().name() << ": " << std::any_cast<int>(a) << '\n';
    a = 3.14;
    std::cout << a.type().name() << ": " << std::any_cast<double>(a) << '\n';
    a = true;
    std::cout << a.type().name() << ": " << std::any_cast<bool>(a) << '\n';

    // bad cast
    try
    {
    a = 1;
    std::cout << std::any_cast<float>(a) << '\n';
    }
    catch (const std::bad_any_cast& e)
    {
    std::cout << e.what() << '\n';
    }

    // has value
    a = 1;
    if (a.has_value())
    {
    std::cout << a.type().name() << '\n';
    }

    // reset
    a.reset();
    if (!a.has_value())
    {
    std::cout << "no value\n";
    }

    // pointer to contained data
    a = 1;
    int* i = std::any_cast<int>(&a);
    std::cout << *i << "\n";
    }

  11. #11

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    کلاس tuple برای استفاده از مقادیر ناهمگن در زمان اجر و بازگشت این مقادیر در قالب یک نوع توسط مقدار بازگشتی یک تابع .
    و متصل کردن مقادیر کلاس به متغیر های اتوماتیک در زمان اجرا به دو روش در 11++c و 17++c


    #include <tuple>
    #include <iostream>
    #include <string>
    #include <stdexcept>

    std::tuple<double, char, std::string> get_student(int id)
    {
    if (id == 0) return std::make_tuple(3.8, 'A', "Lisa Simpson");
    if (id == 1) return std::make_tuple(2.9, 'C', "Milhouse Van Houten");
    if (id == 2) return std::make_tuple(1.7, 'D', "Ralph Wiggum");
    throw std::invalid_argument("id");
    }

    int main()
    {
    // C++‎11 structured binding:
    auto student0 = get_student(0);
    std::cout << "ID: 0, "
    << "GPA: " << std::get<0>(student0) << ", "
    << "grade: " << std::get<1>(student0) << ", "
    << "name: " << std::get<2>(student0) << '\n';

    double gpa1;
    char grade1;
    std::string name1;
    std::tie(gpa1, grade1, name1) = get_student(1);
    std::cout << "ID: 1, "
    << "GPA: " << gpa1 << ", "
    << "grade: " << grade1 << ", "
    << "name: " << name1 << '\n';

    // C++‎17 structured binding:
    auto [ gpa2, grade2, name2 ] = get_student(2);
    std::cout << "ID: 2, "
    << "GPA: " << gpa2 << ", "
    << "grade: " << grade2 << ", "
    << "name: " << name2 << '\n';
    }

  12. #12

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    استفاده از کلاس فوق العاده کارآمد optional برای مدیریت یک مقدار اختیاری در زمان اجرا و یا دسترسی به متغیر استاتیک اتوماتیک تعریف شده در یک تابع با کمک از کلاس reference_wrapper در 17++ C


    #include <string>
    #include <functional>
    #include <iostream>
    #include <optional>

    // optional can be used as the return type of a factory that may fail
    std::optional<std::string> create(bool b) {
    if (b)
    return "Godzilla";
    return {};
    }

    // std::nullopt can be used to create any (empty) std::optional
    auto create2(bool b) {
    return b ? std::optional<std::string>{"Godzilla"} : std::nullopt;
    }

    // std::reference_wrapper may be used to return a reference
    auto create_ref(bool b) {
    static std::string value = "Godzilla";
    return b ? std::optional<std::reference_wrapper<std::string>> {value}
    : std::nullopt;
    }

    int main()
    {
    std::cout << "create(false) returned "
    << create(false).value_or("empty") << '\n';

    // optional-returning factory functions are usable as conditions of while and if
    if (auto str = create2(true)) {
    std::cout << "create2(true) returned " << *str << '\n';
    }

    if (auto str = create_ref(true)) {
    // using get() to access the reference_wrapper's value
    std::cout << "create_ref(true) returned " << str->get() << '\n';
    str->get() = "Farhad";
    std::cout << "modifying it changed it to " << str->get() << '\n';
    }
    }



    #include <functional>
    #include <iostream>

    #define UINT unsigned int

    std::tuple<UINT, UINT> Divide(unsigned int a,unsigned int b)
    {
    UINT q=a/b;
    UINT r=a%b;
    if(a==b*q+r){
    std::cout << "Quotient = " << q << '\n';
    std::cout << "Remainder = " << r << '\n';
    }
    return std::make_tuple(q , r);
    }

    int main()
    {
    auto getDiv = Divide(40,20);
    std::cout << "access defined automatic var in Divide Function into main function" << '\n';
    std::cout << std::get<0>(getDiv) << '\n';
    std::cout << std::get<1>(getDiv) << '\n';

    }
    آخرین ویرایش به وسیله farhad_shiri_ex : سه شنبه 24 مهر 1397 در 08:48 صبح

  13. #13

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    جابجایی دو مقدار در زمان اجرا با استفاده از کلاس exchange در 14++C


    #include <iostream>
    #include <utility>
    #include <vector>
    #include <iterator>

    class stream
    {
    public:

    using flags_type = int;

    public:

    flags_type flags() const
    { return flags_; }

    ///Replaces flags_ by newf, and returns the old value.
    flags_type flags(flags_type newf)
    { return std::exchange(flags_, newf); }

    private:

    flags_type flags_ = 0;
    };

    void f() { std::cout << "f()"; }

    int main()
    {
    stream s;

    std::cout << s.flags(0) << '\n'; //show the 0
    std::cout << s.flags(12) << '\n'; // show the last value is 0 and new value is 12
    std::cout << s.flags(0) << "\n\n"; // show old value is 12 and new valuew is 0

    std::vector<int> v;

    //Since the second template parameter has a default value, it is possible
    //to use a braced-init-list as second argument. The expression below
    //is equivalent to std::exchange(v, std::vector<int>{1,2,3,4});

    std::exchange(v, {1,2,3,4});

    std::copy(begin(v),end(v), std::ostream_iterator<int>(std::cout,", "));

    std::cout << "\n\n";

    void (*fun)();

    //the default value of template parameter also makes possible to use a
    //normal function as second argument. The expression below is equivalent to
    //std::exchange(fun, std::static_cast<void(*)()>(f))
    std::exchange(fun,f);
    fun();
    }

  14. #14

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    با استفاده از std::async می توانید عملیاتهای آسنکرون (همزمانی) برای الگوریتم های خود تهیه کنید. الگوی الگوریتمی که در اینجا مطرح شده است بر اساس تکنیک تقسیم وظایف (Divide By Concur Fork/Join Method) طراحی شده است که میتوان یک مقدار آستانه (Threshold) که ما در این مثال 1000 تعریف کرده ایم تعریف کنید براساس همین مقدار متدها را به صورت بازگشتی با مقادیر مختلف اجرا کنید و در نهایت با استفاده از کلاس std::future مقادیر تمامی task ها را با هم یکسان کرد و در خروجی نمایش داد.
    در مثال فوق پارامتر اول تابع parallel_sum به تعداد پارامترا دوم در هم جمع خواهد شد.
    برای تکنیک فوق با استفاده از کلاس Fork/JoinTask یک مثال هم برای جاوا ر تالار جاوا قرار داده ام.
    حتما باید از کامپایلر C++‎‎11 استفاده نمایید.

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <numeric>
    #include <future>

    template <typename DividedValue>
    int parallel_sum(DividedValue beg, DividedValue end)
    {
    auto len = end - beg;
    if (len < 1000) // divide and conquer
    return std::accumulate(beg, end, 0);

    DividedValue mid = beg + len/2;
    auto handle = std::async(std::launch::async,
    parallel_sum<DividedValue>, mid, end);
    int sum = parallel_sum(beg, mid);
    return sum + handle.get();
    }

    int main()
    {
    std::vector<int> v(110000, 1000);
    std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n';
    }
    آخرین ویرایش به وسیله farhad_shiri_ex : دوشنبه 29 بهمن 1397 در 13:04 عصر

  15. #15

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

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

    #include <iostream>

    #define BYTE unsigned char
    #define NODE 3
    #define BUF 64000l

    using namespace std;

    template<class T, size_t N, size_t Y>
    void genArray(const T (&arr)[N][Y])
    {
    cout << sizeof(arr) << endl;
    cout << *(arr[0]+1) << endl;
    }


    int main()
    {

    BYTE m_CBT[NODE][BUF];
    m_CBT[0][0] = 'a';
    m_CBT[0][1] = 'b';
    m_CBT[0][2] = 'c';
    genArray<BYTE>(m_CBT);
    return 0;
    }

  16. #16

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    استفاده از std::ref , std::cref جهت دسترسی به متغییرهای کلاس اتوماتیک تعریف شده در یک تابع به صورت call by reference درزمان استفاده از کلاس اشاره گر تابع std::function

    تصور کنید که چند متغیر از نوع int دارید و بطور پیش فرض مقدار اولیه ای هم برای آنها در نظر میگیرید و می خواهید از این متغیرها در یک فانکشن استفاده نمائید.
    اگر با استفاده از کلاس std::function یک اشاره گر به تابع بسازید و با استفاده از std::bind پارامترها را هم به فانکشن خود پاس دهید واگر در امضای تابع خود ذکر کرده باشید که مقادیر ورودی با ارجاع باشند، در زمان فراخوانی تابع شما به مقادیر اولیه متغیر ها در زمان تعریف دسترسی خواهید داشت.
    حالا تصور کنید که بعد از bind کردن پارامتراها به اشاره گر تابع مقادیر جدید برای متغیرها ست کردید در اینصورت اگر بازهم تابع خود را فراخوانی کنید خواهید دید که فقط به مقادیر اولیه که ست شده بود باز دسترسی خواهد داشت و مقادیر جدید در دسترس تابع نیستند برای رفع این مشکل دوراه وجود دارد.
    1- بلافاصله بعد از تغییر مقادیر متغیرها با استفاده از دستور bind مجدد پارامترها را برای اشاره گر تابع ست کنید که خوب در اینصورت اگر 100 بار تغییر در مقادیر داشته باشید از نظر منطقی وبهره وری نرم افزاری کار درستی نیست که 100 بار از bind استفاده کنید.
    2- از کلاسهای std::ref برای داده های غیر ثابت و از std::cref برای داده های ثابت می توانید استفاده نمایید.

    همانطور که مشاهده میکنید در مثال زیر در زمان تعریف متغیرهای عددی مقداری برایشان ست کرده ایم و بعد با استفاده از function , bind یک اشاره گر به تابع f ساخته ایم که از سه پارامتر این تابع یک پارامتر را با استفاده از رفرنس معمولی پاس داده ام و دو پارامتر را با استفاده از کلاس ref , cref پاس داده ام و در مر حله بعد مقادیر متغیر ها را تغییر داده ام همانطور که انتظار داشتیم درون بدنه تابع من n مقدار پیش فرض را که در زمان تعریف متغیر ایجاد شده بود در دسترس خواهد داشت تغییرات بعدی را نخواهید دید آنهم به این علت که در بالا توضیح داده شد. ولی دو پارامتر بعدی به آخرین مقدار ست شده در متغییر های اتوماتیک دسترسی خواهند داشت.

    #include <functional>
    #include <iostream>

    void f(int& n1, int& n2, const int& n3)
    {
    std::cout << "In function: " << n1 << ' ' << n2 << ' ' << n3 << '\n';
    ++n1;
    ++n2;
    // ++n3;
    }

    int main()
    {
    int n1 = 1, n2 = 2, n3 = 3;
    std::function<void()> bound_f = std::bind(f, n1, std::ref(n2), std::cref(n3));
    n1 = 10;
    n2 = 11;
    n3 = 12;
    std::cout << "Before function: " << n1 << ' ' << n2 << ' ' << n3 << '\n';
    bound_f();
    std::cout << "After function: " << n1 << ' ' << n2 << ' ' << n3 << '\n' << '\n';

    n1 = 13;
    n2 = 14;
    n3 = 15;
    std::cout << "Before function: " << n1 << ' ' << n2 << ' ' << n3 << '\n';
    bound_f();
    std::cout << "After function: " << n1 << ' ' << n2 << ' ' << n3 << '\n';

    return 0;
    }


  17. #17

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    up!up!up!!up
    آخرین ویرایش به وسیله farhad_shiri_ex : چهارشنبه 26 دی 1397 در 17:51 عصر

  18. #18

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    اشاره به آدرس یک زیرشی subobject در یک مجموعه توسط std::launder
    تصور کنید که یک struct و یک union به این صورت تعریف کردید!

    struct X { const int n; };
    union U { X x; };


    حالا فرض کنید یک شی از union U به این شکل تعریف کردید..

    U u = {{ 1 }};

    خوب حالا اگر بخواهید از مقدار عضو n که در struct X تعریف کردیم توسط شی u دسترسی داشته باشیم بدون اینکه آبجکت جدیدی از struct X بسازیم به روش زیر عمل میکنیم

    X *p = new (&u.x) X {2};

    در اینصورت حالا اشاره گری داریم که به یک عضو از union داره اشاره میکنه! پس عبارتهای زیر هم درست خواهد بود

    assert(p->n == 2); // OK

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

    assert(u.x.n == 2);

    حالا تو C++‎‎‎‎17 این مشکل را می توانید به راحتی با استفاده از تابع std::launder رفع کنید...

    assert(*std::launder(&u.x.n) == 2); // OK

  19. #19

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    اگر بدنبال یک الگوریتم جستجوی باینری برای استفاده در containers هستید پیشنهاد میکنم از Binary_search استفاده کنید!

    #include <iostream>
    #include <algorithm>
    #include <vector>

    int main()
    {
    std::vector<int> haystack {1, 3, 4, 5, 9};
    std::vector<int> needles {1, 2, 3};

    for (auto needle : needles) {
    std::cout << "Searching for " << needle << '\n';
    if (std::binary_search(haystack.begin(), haystack.end(), needle)) {
    std::cout << "Found " << needle << '\n';
    } else {
    std::cout << "no dice!\n";
    }
    }
    }

    جستجوی اعضا وکتور needles در وکتور haystack

  20. #20

    نقل قول: آموزش پلی مورفیسم در ++C و نحوه استفاده از اشاره گرهای هوشمند

    قبلا یک مثال درباره Curiously recurring template pattern اشاره کرده بودم مثال ساده تری از این تکنیک را در این جا بیان خواهم کرد.
    تصور کنید یک کلاس پایه به نام shape دارید که یک متد clone داره که به صورت virtual تعریف شده بنابراین تمامی کلاسهایی که این کلاس را به ارث میبرند باید متد فوق را بازنویسی کنند خوب تا اینجا کاری هست که معمولا انجام میدهیم که البته برای متدهای غیر ژنریک روش خوبی هست.
    ولی برای متدهایی مثل همین clone که به صورت ژنریک هستند یعنی کار این متد ساختن یک شی جدید از کلاس derived هست.! در تمامی کلاسها مانند کلاس دایره و مربع و ... بنابراین این متدها گزینه های مستعدی جهت استفاده از الگوی CRTP هستند.
    بنابراین در تکه سورس زیر یک کلاس پایه shape داریم با متد clone و یک کلاس کمکی میانی داریم که پیاده سازی متد clone در آن تعریف شده است واز این پس هر کلاس جدیدی که از خانواده shape تعریف شود متد clone دیگر نیازی به بازنویسی در کلاس جدید را نخواهد داشت و به راحتی یک شی از کلاس جدید به عنوان خروجی خواهد ساخت.

    // Base class has a pure virtual function for cloning
    class Shape {
    public:
    virtual ~Shape() {};
    virtual Shape *clone() const = 0;
    };
    template <typename Derived>
    class Shape_CRTP : public Shape {
    public:
    virtual Shape* clone() const {
    return new Derived(static_cast<Derived const&>(*this));
    }
    };


    #define Derive_Shape_CRTP(Type) class Type: public Shape_CRTP<Type>


    // Every derived class inherits from Shape_CRTP instead of Shape
    //use by macro
    Derive_Shape_CRTP(Square) {

    };
    Derive_Shape_CRTP(Circle) {

    };
    //or standard usage
    class tringle : public Shape_CRTP<tringle>{


    }

    حال اگر از این تکنیک نخواهید استفاده کنید باید در هریک از کلاسهای دایره و مربع و مثلث و... متد clone را بازنویسی کنید که خوب از نظر نگهداری کد هم بهینه نیست!
    آرزویی که زبانهای سطح بالاتر که مفاهیم template ها را به یک روشهایی مثل ژنریک ها در سی شارپ و جاوا تعبیه کرده اند ولی قطعا چنین دسترسی هایی به پارامترهای الگوها ندارند.

تاپیک های مشابه

  1. مبتدی: نحوه استفاده از اشاره گر
    نوشته شده توسط WhiteWorld در بخش C#‎‎
    پاسخ: 6
    آخرین پست: جمعه 27 دی 1392, 21:06 عصر
  2. توضیح در مورد کد نحوه استفاده از تاریخ شمسی
    نوشته شده توسط boysfe5 در بخش C#‎‎
    پاسخ: 3
    آخرین پست: شنبه 05 مرداد 1392, 17:24 عصر
  3. سوال: نحوه استفاده از اشاره گر this
    نوشته شده توسط irn.2022 در بخش برنامه نویسی با زبان C و ++C
    پاسخ: 1
    آخرین پست: یک شنبه 18 دی 1390, 11:34 صبح
  4. آموزش نحوه استفاده از ُSQL SERVER در delphi !
    نوشته شده توسط ghaem در بخش بانک های اطلاعاتی در Delphi
    پاسخ: 9
    آخرین پست: دوشنبه 14 آذر 1384, 18:37 عصر
  5. نحوه استفاده از اشاره گر
    نوشته شده توسط idic1 در بخش برنامه نویسی در Delphi
    پاسخ: 2
    آخرین پست: دوشنبه 22 فروردین 1384, 09:26 صبح

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •