
یادگیری سی شارپ از مفاهیم پایه تا پروژه محور: شیگرایی، کار با SQL و LINQ، ORMها (Entity Framework)، ساخت پروژه مدیریت رستوران با گزارشات حرفهای و امکانات کامل!
مشاهده بیشتر
یادگیری MVC Core از مبانی تا پیشرفته: شیگرایی، Routing، Entity Framework، امنیت، تست یونیت، Razor، Ajax، و پروژههای کاربردی! یک دوره کامل برای تسلط بر توسعه وب با ASP.NET Core. به صورت حضوری و آنلاین!
مشاهده بیشترمشخصات مقاله
شی گرایی در ++C
OOP مخفف عبارت Object-Oriented Programming است. برنامه نویسی رویه ای در مورد نوشتن رویه ها یا توابعی است که عملیات را بر روی داده ها انجام می دهند، در حالی که برنامه نویسی شی گرا در مورد ایجاد اشیایی است که هم داده ها و هم توابع را شامل می شود.
در برنامه نویسی شی گرا در ابتدا مفهومی به نام کلاس تعریف و استفاده می شود. در کلاس تعدادی شی به صورت private و public تعریف می گردند که متناسب با نیاز برنامه نویس در کد فراخوانی می شوند. بنابراین، یک کلاس یک الگو برای اشیاء است، و یک شی نمونه ای از یک کلاس است. هنگامی که اشیاء منفرد ایجاد می شوند، تمام متغیرها و توابع را از کلاس به ارث می برند.
برنامه نویسی شی گرا دارای چندین مزیت نسبت به برنامه نویسی رویه ای است:
- • برای اجرا OOP سریعتر و آسانتر است.
- • OOP یک ساختار واضح برای برنامه ها فراهم می کند.
- • OOP کمک می کند تا کد C++ DRY "Don't Repeat Yourself" نگه داشته شود و نگهداری، اصلاح و اشکال زدایی کد را آسان تر می کند. اصل "تکرار نکنید" (DRY) در مورد کاهش تکرار کد است. شما باید کدهایی را که برای برنامه رایج هستند استخراج کنید و آنها را در یک مکان قرار دهید و به جای تکرار از آنها استفاده مجدد نمایید.
- • OOP امکان ایجاد برنامه های کاربردی قابل استفاده مجدد را با کد کمتر و زمان توسعه کوتاه تر ایجاد می نماید.
کلاسها و اشیا در C++
C++ یک زبان برنامه نویسی شی گرا است. همه چیز در C++ با کلاس و اشیاء همراه با ویژگی ها و متدهای آن مرتبط است. به عنوان مثال، در زندگی واقعی، ماشین یک شی است. ماشین دارای ویژگی هایی مانند وزن و رنگ و ترمز است. ویژگی ها و متدها اساساً متغیرها و توابعی هستند که به کلاس تعلق دارند. این اشیا اغلب به عنوان "اعضای کلاس" نامیده می شوند. کلاس یک نوع داده تعریف شده توسط کاربر است که می توانیم در برنامه خود از آن استفاده کنیم.
ایجاد کلاس (class)
برای ایجاد یک کلاس، از کلمه کلیدی class استفاده و کلاسی به نام MyClass ایجاد نمایید:
class MyClass { // The class public: // Access specifier int myNum; // Attribute (int variable) string myString; // Attribute (string variable) };
کلمه کلیدی class برای ایجاد کلاسی به نام MyClass استفاده شده است. کلمه publicمشخص می کند اعضای (ویژگی ها و متدها) خارج از کلاس نیز قابل دسترسی هستند. در داخل کلاس، یک متغیر عدد صحیح myNum و یک متغیر رشته ای myString وجود دارد. هنگامی که متغیرها در یک کلاس صدا زده می شوند، به آنها ویژگی (Attribute) می گویند. در نهایت، تعریف کلاس را با نقطه ویرگول خاتمه می یابد.
یک شی بسازید!
در C++ یک شی از یک کلاس ایجاد می شود. قبلاً کلاسی به نام MyClass ایجاد کردهایم، بنابراین اکنون میتوانیم از آن برای ایجاد اشیا استفاده کنیم. برای ایجاد یک شی از MyClass، نام کلاس و به دنبال آن نام شی را مشخص نمایید. برای دسترسی به ویژگی های کلاس (myNum و myString)، از دستور نقطه (.) روی شی استفاده نمایید. برای مثال یک شی به نام myObj ایجاد و به ویژگی ها دسترسی پیدا کنید:
#include#include using namespace std; class MyClass { // The class public: // Access specifier int myNum; // Attribute (int variable) string myString; // Attribute (string variable) }; int main() { MyClass myObj; // Create an object of MyClass // Access attributes and set values myObj.myNum = 15; myObj.myString = "Some text"; // Print values cout << myObj.myNum << "\n"; cout << myObj.myString; return 0; }
خروجی :
- 15
- Some text
Multiple Objects
شما می توانید چندین شی از یک کلاس ایجاد کنید:
#include#include using namespace std; class Car { public: string brand; string model; int year; }; int main() { Car carObj1; carObj1.brand = "BMW"; carObj1.model = "X5"; carObj1.year = 1999; Car carObj2; carObj2.brand = "Ford"; carObj2.model = "Mustang"; carObj2.year = 1969; cout << carObj1.brand << " " << carObj1.model << " " << carObj1.year << "\n"; cout << carObj2.brand << " " << carObj2.model << " " << carObj2.year << "\n"; return 0; }
خروجی :
- BMW X5 1999
- Ford Mustang 1969
متدهای کلاس (Class Methods)
متدها توابعی هستند که به کلاس تعلق دارند. دو روش برای تعریف توابع متعلق به یک کلاس وجود دارد:
- • تعریف داخل کلاس
- • تعریف خارج از کلاس
در مثال زیر تابع را در داخل کلاس تعریف می کنیم و نام آن را myMethod می گذاریم.
#includeusing namespace std; class MyClass { // The class public: // Access specifier void myMethod() { // Method/function cout << "Hello World!"; } }; int main() { MyClass myObj; // Create an object of MyClass myObj.myMethod(); // Call the method return 0; }
خروجی :
Hello World!
برای تعریف تابعی خارج از کلاس، باید آن را در داخل کلاس تعریف و سپس خارج از کلاس تعریف کنید. این کار با مشخص کردن نام کلاس، به دنبال عملگر scope :: و به دنبال آن نام تابع انجام می شود:
#includeusing namespace std; class MyClass { // The class public: // Access specifier void myMethod(); // Method/function declaration }; // Method/function definition outside the class void MyClass::myMethod() { cout << "Hello World!"; } int main() { MyClass myObj; // Create an object of MyClass myObj.myMethod(); // Call the method return 0; }
خروجی :
Hello World!
پارامترها (Parameters)
شما همچنین می توانید به تابع پارامتراضافه کنید:
#includeusing namespace std; class Car { public: int speed(int maxSpeed); }; int Car::speed(int maxSpeed) { return maxSpeed; } int main() { Car myObj; cout << myObj.speed(200); return 0; }
خروجی :
200
سازنده (Constructors)
سازنده در C++ یک متد خاص است که به طور خودکار هنگام ایجاد یک شی از یک کلاس فراخوانی می شود. برای ایجاد یک سازنده، از همان نام کلاس و به دنبال آن پرانتز () استفاده می کنیم. سازنده همان نام کلاس، همیشه عمومی است و هیچ مقدار بازگشتی ندارد.
#includeusing namespace std; class MyClass { // The class public: // Access specifier MyClass() { // Constructor cout << "Hello World!"; } }; int main() { MyClass myObj; // Create an object of MyClass (this will call the constructor) return 0; }
خروجی :
Hello World!
پارامترهای سازنده (Constructor Parameters)
سازنده ها همچنین پارامترهایی (درست مانند توابع معمولی) می گیرند که می تواند برای تنظیم مقادیر اولیه برای ویژگی ها مفید باشد. کلاس زیر دارای ویژگی های برند، مدل ، سال و سازنده با پارامترهای مختلف است.
در داخل سازنده، ما صفات را برابر با پارامترهای سازنده (brand=x و ...) قرار می دهیم. هنگامی که سازنده را فراخوانی می کنیم (با ایجاد یک شی از کلاس)، پارامترهایی را به سازنده منتقل می کنیم، که مقدار ویژگی های مربوطه را به همان اندازه تنظیم می کند:
#includeusing namespace std; class Car { // The class public: // Access specifier string brand; // Attribute string model; // Attribute int year; // Attribute Car(string x, string y, int z) { // Constructor with parameters brand = x; model = y; year = z; } }; int main() { // Create Car objects and call the constructor with different values Car carObj1("BMW", "X5", 1999); Car carObj2("Ford", "Mustang", 1969); // Print values cout << carObj1.brand << " " << carObj1.model << " " << carObj1.year << "\n"; cout << carObj2.brand << " " << carObj2.model << " " << carObj2.year << "\n"; return 0; }
خروجی :
- BMW X5 1999
- Ford Mustang 1969
درست مانند توابع، سازنده ها نیز می توانند خارج از کلاس تعریف شوند. ابتدا سازنده را در داخل کلاس اعلان کنید و سپس آن را خارج از کلاس با مشخص کردن نام کلاس و سپس عملگر scope :: و به دنبال آن نام سازنده (که همان کلاس است) تعریف نمایید.
#includeusing namespace std; class Car { // The class public: // Access specifier string brand; // Attribute string model; // Attribute int year; // Attribute Car(string x, string y, int z); // Constructor declaration }; // Constructor definition outside the class Car::Car(string x, string y, int z) { brand = x; model = y; year = z; } int main() { // Create Car objects and call the constructor with different values Car carObj1("BMW", "X5", 1999); Car carObj2("Ford", "Mustang", 1969); // Print values cout << carObj1.brand << " " << carObj1.model << " " << carObj1.year << "\n"; cout << carObj2.brand << " " << carObj2.model << " " << carObj2.year << "\n"; return 0; }
خروجی :
در حال حاضر، شما با کلمه کلیدی عمومی که در تمام نمونه های کلاس ما ظاهر می شود کاملاً آشنا هستید:
#includeusing namespace std; class MyClass { // The class public: // Public access specifier int x; // Public attribute (int variable) }; int main() { MyClass myObj; // Create an object of MyClass // Access attributes and set values myObj.x = 15; // Print values cout << myObj.x; return 0; }
خروجی :
15
کلمه کلیدی Public مشخص کننده سطح دسترسی است. مشخصکنندههای دسترسی نحوه دسترسی به اعضا (ویژگیها و متدها) یک کلاس را تعریف میکنند. در مثال بالا، اعضا Public هستند، به این معنی که می توان از خارج از کد به آنها دسترسی داشت و تغییر ایجاد کرد. در C++ سه مشخص کننده دسترسی وجود دارد:
- Public - اعضا خارج از کلاس قابل دسترسی هستند.
- Private - اعضای خارج از کلاس قابل دسترسی (یا مشاهده) نیستند.
- Protected- اعضا را نمی توان خارج از کلاس داشت، با این حال، می توان به آنها در کلاس های ارثی دسترسی پیدا نمود.
در مثال زیر، تفاوتهای بین اعضای عمومی و خصوصی را نشان میدهیم:
#includeusing namespace std; class MyClass { public: // Public access specifier int x; // Public attribute private: // Private access specifier int y; // Private attribute }; int main() { MyClass myObj; myObj.x = 25; // Allowed (x is public) myObj.y = 50; // Not allowed (y is private) return 0; }
خروجی :
- In function 'int main()':
- Line 8: error: 'int MyClass::y' is private
- Line 14: error: within this context
نکته: دسترسی به اعضای خصوصی یک کلاس با استفاده از متد public در همان کلاس امکان پذیر است. این عمل خوبی است که ویژگی کلاس خود را به عنوان خصوصی اعلام کنید.
class MyClass { int x; // Private attribute int y; // Private attribute };
کپسوله سازی (Encapsulation)
منظور از Encapsulation، این است که اطمینان حاصل شود ، داده های مهم از کاربران پنهان هستند. برای رسیدن به این هدف، شما باید متغیرها/ویژگی های کلاس را خصوصی اعلام نمایید.
دسترسی به اعضای خصوصی
برای دسترسی به یک ویژگی خصوصی، از روش های عمومی "get" و "set" استفاده کنید:
#includeusing namespace std; class Employee { private: int salary; public: void setSalary(int s) { salary = s; } int getSalary() { return salary; } }; int main() { Employee myObj; myObj.setSalary(50000); cout << myObj.getSalary(); return 0; }
خروجی :
50000
متد public setSalary() یک پارامتر (s) می گیرد و آن را به ویژگی salary (salary = s) اختصاص می دهد. متد ()getSalary مقدار مشخصه private salary را برمیگرداند. در داخل main()، یک شی از کلاس Employee ایجاد می کنیم. اکنون میتوانیم از متد setSalary() برای تنظیم مقدار خصوصیت خصوصی به 50000 استفاده کنیم. سپس متد getSalary() را روی شیء فراخوانی میکنیم تا مقدار را برگردانیم.
چرا Encapsulation ؟
- • کپسولهسازی کنترل بهتر دادههای شما را تضمین میکند، زیرا شما میتوانید بخشی از کد را بدون تأثیرگذاری بر سایر قسمتها تغییر دهید.
- • افزایش امنیت داده ها
وراثت (Inheritance)
در C++ امکان ارث بردن صفات و متدها از یک کلاس به کلاس دیگر وجود دارد. ما مفهوم وراثت را به دو بخش، دسته بندی می کنیم:
- کلاس مشتق شده (فرزند) - کلاسی که از کلاس دیگری به ارث می برد.
- کلاس پایه (والد) - کلاسی که از آن به ارث برده می شود.
برای ارث بردن از یک کلاس، از نماد ":" استفاده نمایید. در مثال زیر، کلاس Car (فرزند) ویژگی ها و متدها را از کلاس Vehicle (والد) به ارث می برد:
#include#include using namespace std; // Base class class Vehicle { public: string brand = "Ford"; void honk() { cout << "Tuut, tuut! \n" ; } }; // Derived class class Car: public Vehicle { public: string model = "Mustang"; }; int main() { Car myCar; myCar.honk(); cout << myCar.brand + " " + myCar.model; return 0; }
خروجی :
- Tuut, tuut!
- Ford Mustang
چرا و چه زمانی از ارث بری استفاده نماییم؟
برای قابلیت استفاده مجدد کد مفید است: هنگامی که یک کلاس جدید ایجاد می کنید از ویژگی ها و روش های یک کلاس موجود استفاده نمایید.
وراثت چند سطحی
یک کلاس همچنین می تواند از یک کلاس مشتق شود که قبلاً از کلاس دیگری مشتق شده. در مثال زیر، MyGrandChild از کلاس MyChild (که از MyClass مشتق شده است) مشتق شده است.
#includeusing namespace std; // Parent class class MyClass { public: void myFunction() { cout << "Some content in parent class." ; } }; // Child class class MyChild: public MyClass { }; // Grandchild class class MyGrandChild: public MyChild { }; int main() { MyGrandChild myObj; myObj.myFunction(); return 0; }
خروجی :
Some content in parent class.
ارث بری چندگانه (Multiple Inheritance)
یک کلاس همچنین می تواند از بیش از یک کلاس پایه با استفاده از یک لیست جدا شده با کاما مشتق شود:
#includeusing namespace std; // Base class class MyClass { public: void myFunction() { cout << "Some content in parent class.\n" ; } }; // Another base class class MyOtherClass { public: void myOtherFunction() { cout << "Some content in another class.\n" ; } }; // Derived class class MyChildClass: public MyClass, public MyOtherClass { }; int main() { MyChildClass myObj; myObj.myFunction(); myObj.myOtherFunction(); return 0; }
خروجی :
- Some content in parent class.
- Some content in another class.
پلی مورفیسم (Polymorphism)
Polymorphism به معنای "چند شکلی" است و زمانی اتفاق می افتد که ما کلاس های زیادی داشته باشیم که از طریق ارث به یکدیگر مرتبط هستند؛ وراثت به ما اجازه می دهد تا ویژگی ها و متدها را از کلاس دیگری به ارث ببریم. پلی مورفیسم از آن روش ها برای انجام وظایف مختلف استفاده می کند. این مسئله به ما اجازه می دهد تا یک عمل واحد را به روش های مختلف انجام دهیم.
به عنوان مثال، یک کلاس پایه به نام Animal را در نظر بگیرید که متدی به نام () animalSound دارد. کلاس های مشتق شده از حیوانات می تواند خوک ها، گربه ها، سگ ها، پرندگان باشند:
// Base class class Animal { public: void animalSound() { cout << "The animal makes a sound \n"; } }; // Derived class class Pig : public Animal { public: void animalSound() { cout << "The pig says: wee wee \n"; } }; // Derived class class Dog : public Animal { public: void animalSound() { cout << "The dog says: bow wow \n"; } };
از فصل Inheritance به یاد داشته باشید که برای ارث بردن از یک کلاس از نماد : استفاده می کنیم. اکنون میتوانیم اشیاء Pig and Dog ایجاد کنیم و متد () animalSound را لغو کنیم:
#include#include using namespace std; // Base class class Animal { public: void animalSound() { cout << "The animal makes a sound \n"; } }; // Derived class class Pig : public Animal { public: void animalSound() { cout << "The pig says: wee wee \n"; } }; // Derived class class Dog : public Animal { public: void animalSound() { cout << "The dog says: bow wow \n"; } }; int main() { Animal myAnimal; Pig myPig; Dog myDog; myAnimal.animalSound(); myPig.animalSound(); myDog.animalSound(); return 0; }
خروجی :
- The animal makes a sound
- The pig says: wee wee
- The dog says: bow wow
استثناها در++C
هنگام اجرای کد ++C، خطاهای مختلفی ممکن است رخ دهد (خطاهای کدنویسی توسط برنامه نویس، خطاهای ناشی از ورودی اشتباه یا موارد غیر قابل پیش بینی دیگر). هنگامی که خطایی رخ می دهد، ++C به طور معمول متوقف شده و یک پیام خطا ایجاد می کند. اصطلاح فنی برای این است: ++C یک استثنا ایجاد می کند (پرتاب یک خطا).
++C را امتحان کنید …
مدیریت استثنا در++C از سه کلمه کلیدی تشکیل شده است: try، throw ، catch. دستور try به شما این امکان را می دهد که یک بلوک از کد را تعریف کنید تا در حین اجرا برای خطاها آزمایش شود. هنگامی که مشکلی شناسایی می شود، کلمه کلیدی throw یک استثنا ایجاد می کند، که به ما اجازه می دهد یک خطای سفارشی ایجاد کنیم. دستور catch به شما این امکان را می دهد که در صورت بروز خطا در بلوک try، یک بلوک از کد را برای اجرا تعریف کنید.
try { // Block of code to try throw exception; // Throw an exception when a problem arise } catch () { // Block of code to handle errors }
به مثال زیر توجه کنید:
#includeusing namespace std; int main() { try { int age = 15; if (age >= 18) { cout << "Access granted - you are old enough."; } else { throw (age); } } catch (int myNum) { cout << "Access denied - You must be at least 18 years old.\n"; cout << "Age is: " << myNum; } return 0; }
خروجی :
- Access denied - You must be at least 18 years old.
- Age is: 15
در بلوک catch، خطا را می گیریم و کاری برای آن انجام می دهیم. دستور catch پارامتری را می گیرد. در مثال ما از یک متغیر int (myNum) استفاده می کنیم (زیرا یک استثنا از نوع int را در بلوک try (age) می اندازیم)، تا مقدار age را به دست آوریم.
اگر خطایی رخ ندهد (به عنوان مثال اگر سن به جای 15 سال 20 باشد، به این معنی که بیشتر از 18 سال خواهد بود)، بلوک catch نادیده گرفته می شود:
#includeusing namespace std; int main() { try { int age = 20; if (age >= 18) { cout << "Access granted - you are old enough."; } else { throw (age); } } catch (int myNum) { cout << "Access denied - You must be at least 18 years old.\n"; cout << "Age is: " << myNum; } return 0; }
خروجی :
Access granted - you are old enough.
همچنین میتوانید از کلمه کلیدی throw برای خروجی یک شماره مرجع، مانند شماره/کد خطای سفارشی برای اهداف سازماندهی استفاده نمایید:
#includeusing namespace std; int main() { try { int age = 15; if (age >= 18) { cout << "Access granted - you are old enough."; } else { throw 505; } } catch (int myNum) { cout << "Access denied - You must be at least 18 years old.\n"; cout << "Error number: " << myNum; } return 0; }
خروجی :
- Access denied - You must be at least 18 years old.
- Error number: 505