অবজেক্ট অরিয়েন্টেড সি++ ক্লাশ এবং অবজেক্টস

সি++ প্রোগ্রামিং এর আসল
উদ্দেশ্য হচ্ছে সি প্রোগ্রমিং এর মধ্যে অবজেক্ট অরিয়েন্টেশন যুক্ত করা এবং সি++ class গুলো
হচ্ছে এর প্রধান ফিচার যেটার কারনে সি++ অবজেক্ট অরিয়েন্টেশন সাপোর্ট করে।

একটি class এর
কাজ হচ্ছে অবজেক্টটি কীভাবে কোন আকার ধারন করবে তা স্পেসিফাই করা এবং এই অবজেক্টটি
কীভাবে ডেটা রিপ্রেসেন্ট করবে এবং কোন পদ্ধতি ব্যবহার করে ডেটা ম্যানুপুলেট করবে
তা সব ঠিক করে একটা নিট প্যাকেজ তৈরি করা। Class এর ভিতর
থাকা ডেটা এবং ফাংশন গুলো কে Member of the Class বলে।

ক্লাশ ডিফাইন করা (Defining Class)

অবজেক্ট অরিয়েন্টেড
প্রোগ্রামিং ওয়ার্ল্ডএ আমরা বেশিরভাগ সময় আমাদের ডেটা টাইপস গুলো দিয়ে শুধু ডেটাই
হোল্ড করতে চাই না, পাশাপাশি সেই ডেটার সাথে কাজ করে এমন ফাংশন প্রোভাইড
করতে চাই। সি++ অবজেক্ট অরিয়েন্টেশনে এই কাজটাই করে class। আমরা class ব্যবহার
করে নতুন ইউসার-টাইপ ডিফাইন করতে পারি যেটাকে বলে class টাইপ।

ক্লাশ
ডিফাইন করার জন্য প্রথমে class কীওয়ার্ডটি লিখতে হয় এবং এরপর সেই ক্লাশের নাম। ক্লাশের বডিটি {}
বন্ধনীর ভিতরে অবস্থান করবে। ক্লাশ ডিফাইন করার সিনট্যাক্স –

class class_name {
  access_modifiers_type:
     data_type member_name;
};

এখানে
access modifiers type টি হতে পারে public, private অথবা protected ধরণের। এই
তিনটি টাইপ দিয়ে ডিফাইন করা হয় এই ক্লাশটিকে কে কোথায় এক্সেস করতে পারবে। যেমন –
public মেম্বারকে ক্লাশের বাইরে প্রোগ্রামের ভিতর যেকোনো জায়গা থেকে এক্সেস করা
যাবে। আমরা এই access modifiers নিয়ে পরের অধ্যায় (২০) এ আলোচনা করেছি।

উপরের সিনট্যাক্স ব্যবহার করে
আমরা এখন একটি গাড়ির ক্লাশ ডিফাইন করবো –

class Box {
  public:
    double length;
    double breadth;
    double height;
}

সি++ অবজেক্টস ডিফাইন করা (Defining C++ Objects)

ক্লাশ হচ্ছে অবজেক্টের ব্লুপ্রিন্ট অথবা নীল-নকশা, কারন অবজেক্ট একটি ক্লাশ থেকে
তৈরি হয়। আমরা যেভাবে ভ্যারিয়েবল ডিক্ল্যায়ার করি, ঠিক সেভাবেই একটি ক্লাশের অবজেক্টস
ডিক্ল্যায়ার করতে পারি। যেমন –

Box box1;             // Declare box1 of type Box
Box box2;             // Declare box2 of type Box

উভয় car1 এবং car2 অবজেক্টের আলাদা আলাদা ডেটা মেম্বার থাকবে।

ডেটা মেম্বার এক্সেস করা (Accessing Data Members)

ডেটা স্ট্র্যাকচার আমরা যেভাবে (.) এক্সেস অপারেটর ব্যবহার করে ডেটা মেম্বার এক্সেস করেছিলাম, ক্লাশ এবং অবজেক্টের ক্ষেত্রে সেরকম। একটি উদাহরণ দেখলে বুঝা যাবে –

#include <iostream>
using namespace std;

class Box {
    public:
        double length;
        double breadth;
        double height;
};

int main() {
    Box box1;
    Box box2;
    double volume = 0.0;
    
    // box1 specs
    box1.length = 3.0;
    box1.breadth = 5.0;
    box1.height = 7.0;
    
    // box2 specs
    box2.length = 6.0;
    box2.breadth = 8.0;
    box2.height = 10.0;
    
    // volume of box1
    volume = box1.length * box1.breadth * box1.height;
    cout << "volume of box1: " << volume << endl;
    
    // volume of box2
    volume = box2.length * box2.breadth * box2.height;
    cout << "volume of box2: " << volume << endl;
    
    return 0;
}

আউটপুট হবে –

volume of box1: 105
volume of box2: 480

নোট – private এবং protected ডেটা মেম্বারদেরকে (.) মেম্বার এক্সেস অপারেটর ব্যবহার করে সরাসরি এক্সেস করা যায় না। আরো জানতে রেফার করুন  –https://bit.ly/2C8uCvw

ক্লাশ মেম্বার ফাংশন (Class Member Function)

এবার কথা বলি মেম্বার ফাংশন (Member Functions) নিয়ে।
Class ডেটা হোল্ড করার পাশাপাশি ফাংশনও হোল্ড করতে পারে।
তখন সেই ফাংশন কে Class এর Member Functions বলে। Member Functions গুলো কে চাইলে class
এর ভেতরে অথবা বাইরে ডিফ্যাইন করা যায়। আমরা এখন class এর ভিতরে মেম্বার ফাংশন ডিফ্যাইন কীভাবে করে সেটা দেখবো।

আমরা ডেট প্রিন্ট করার
জন্য এখন মেম্বার ফাংশন ব্যবহার করে একটি class তৈরি করবো।

class DateClass {
  public:
     int m_year;
     int m_month;
     int m_day;
  
     void print() {           // defines a member function named 
                              //print()
        cout << m_year << “/ ” << m_month << “/ “ << m_day << endl;
     }
};

পুরো প্রোগ্রামটি –

#include <iostream>
using namespace std;

class DateClass {
    public:
        int m_year;
        int m_month;
        int m_day;
        void print() {
            cout << m_year << "/" << m_month << "/" << m_day << endl;
        }
};

int main() {
    DateClass today {2018, 9, 1};
    
    today.m_day = 2;        // use member selection operator to
                            // select a member variable of the class
    today.print();
    return 0;
}

এই কোডটি রান করলে এটি
ডেটটি প্রিন্ট করবে —

2018/9/2

আমরা যখন কোডে today.print() কল করলাম তখন আমরা
কম্পাইলারকে বলছিলাম এটা যেন DateClass অবজেক্ট থেকে print()
মেম্বার ফাংশনকে কল করে। কারন প্রতিটি মেম্বার ফাংশন গুলো অবশ্যই
class এর অবজেক্টের সাথে যুক্ত।

চলেন আবার আমাদের print() মেম্বার
ফাংশনটিকে দেখি —

void print() {
   cout << m_year << "/" << m_month << "/" << m_day << endl;
}

এখানে m_year, m_month, m_day আসলে কাকে রেফার করে? এরা class এর অবজেক্টের সাথে যুক্ত।

আমরা যখন today.print() কল করলাম তখন কম্পাইলারটা m_year কে today.m_year
হিসেবে ধরে নেয়, আবার আমরা যখন yesterday.print()
কে কল করবো কম্পাইলার তখন m_year কে yesterday.m_year
হিসেবে ধরে নিবে। এই সিস্টেমটাকে The Implicit
Object 
বলে। এখানে “m_” দিয়ে আমরা member variables বুঝিয়েছি, ফলে আমরা কোড দেখলে বুঝতে পারবো যে এই ভ্যারিয়েবলটি অন্যান্য সাধারণ
অথবা লোকাল ভ্যারিয়েবল থেকে আলাদা। Member Functions এর
ক্ষেত্রে আমরা সবসময় ধরে নেই যে আমাদের Implicit Object ডেটা
রয়েছে যেটা নিয়ে class কাজ করতে পারবে যেকোনো সময়। কিন্তু
Non-Member Functions এর সময় আলাদা ভাবে ডেটা পাস করতে
হয়।

আরো
একটি প্রোগ্রাম উদাহরণ –

#include <iostream>
#include <string>

using namespace std;

class CarMake {
    public:
        string m_make;
        string m_model;
        int m_year;
        float m_price;
        
        void print() {
            cout << "Car Make: " << m_make << ", Car Model: " << m_model << ", Car Build Year: " << m_year << ", Car Price: $" << m_price << " USD." << endl;
        }
};

int main() {
    CarMake ferrari {"Ferrari", "LaFerrari", 2015, 100000.00};
    CarMake bugatti {"Bugatti", "Chiron", 2017, 250000.00};
    
    ferrari.print();
    bugatti.print();
    
    return 0;
}

আউটপুট

Car Make: Ferrari, Car Model: LaFerrari, Car Build Year: 2015, Car Price: $100000 USD.
Car Make: Bugatti, Car Model: Chiron, Car Build Year: 2017, Car Price: $250000 USD.

মেম্বার ফাংশন সিস্টেমে
সবচেয়ে মজার ব্যাপার হচ্ছে, অন্যান্য নরমাল ফাংশনের মতোন এখানে কোনো প্রকার অর্ডার
ম্যান্টেইন করে ফাংশন ডিফ্যাইন করতে হয় না। যখন যেখানে ইচ্ছা সেখানেই মেম্বার
ফাংশন ডিফাইন করা যায়।

ফ্রেন্ড ক্লাশ এবং ফাংশন (Friend Class & Functions)

ফ্রেন্ড
ক্লাশঃ
একটি ফ্রেন্ড ক্লাস অন্য ক্লাশের প্রাইভেট এবং
প্রোটেকটেড মেম্বারদের এক্সেস করতে পারে। যেমন –

class A {
  private:
     int a;

  friend class B;    // Now class B can access private members of A
};

ফ্রেন্ড
ক্লাশের একটি প্রোগ্রামিং উদাহরণ –

#include <iostream>
using namespace std;

class A {
    private:
        int a;
    
    public:
        A() { a=0; }
        friend class B;     // Friend Class
};
class B {
    private:
        int b;
        
    public:
        void showA (A& x) {
            // Since B is friend of A, it can access private members of A
            cout << "A::a is: " << x.a;
        }
};

int main() {
    A a;
    B b;
    b.showA(a);
    
    return 0;
}

আউটপুট

A::a is: 0

ফ্রেন্ড
ফাংশনঃ
ফ্রেন্ড ক্লাশের মতোন, একটি ফ্রেন্ড ফাংশনও একটি
ক্লাশের প্রাইভেট এবং প্রোটেকটেড মেম্বারদের এক্সেস করতে পারে। ফ্রেন্ড ফাংশন একটি
গ্লোবাল ফাংশনও হতে পারে আবার আরেকটি ক্লাশের একটি ম্যাথোডও হতে পারে।

class A {
  private:
     int a;

  friend int B::functionName();    // only functionName() of B can access internal members
};

ফ্রেন্ড
ফাংশনের একটি প্রোগ্রামিং উদাহরণ –

#include <iostream>
using namespace std;

class B;

class A {
    public:
        void showB (B&);
};

class B {
    private:
        int b;
        
    public:
        B() { b=0; }
        friend void A::showB(B& x);         // Friend Function
};

void A::showB (B& x) {
    // since showB() is friend of B, it can access private members of B
    cout << "B::b is: " << x.b << endl;
}

int main() {
    A a;
    B x;
    a.showB(x);
    
    return 0;
}

আউটপুট

B::b is: 0

ফ্রেন্ড
ফাংশন এবং ক্লাশের কিছু গুরুত্বপূর্ণ পয়েন্টস –

  • ফ্রেন্ড ম্যাথোডটা অল্প সংখ্যক কাজের জন্য ব্যবহার
    করতে হবে। কারন যদি অনেক গুলো ফাংশন এবং ক্লাশ কে, যে ক্লাশের প্রাইভেট এবং
    প্রোটেকটেড ডেটা মেম্বার রয়েছে তার ফ্রেন্ড হিসেবে ডিফাইন করা হয়, তাহলে এটি
    অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং এনক্যাপসুলেশন এর ভ্যালু কমিয়ে দিবে।
  • অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং এ ফ্রেন্ডসিপ
    মিচ্যুয়াল নয়। A হচ্ছে B এর ফ্রেন্ড কিন্তু তারমানে এই না যে B অটোম্যাটিকভাবে A এর ফ্রেন্ড হয়ে যাবে। অর্থাৎ B, A এর প্রাইভেট প্রোটেকটেড মেম্বারদের এক্সেস করতে
    পারবে, কিন্তু A, B এর প্রাইভেট
    প্রোটেকটেড মেম্বারদের এক্সেস করতে পারবে না।
  • সি++ এ ফ্রেন্ডসিপ ইনিহেরিটেড নয়।
    অর্থাৎ যদি Base ক্লাশ এর একটি ফ্রেন্ড ফাংশন
    থাকে, তারমানে এই নয় যে ফাংশনটি Derived ক্লাশেরও
    ফ্রেন্ড হয়ে যাবে।

ইনলাইন ফাংশন (Inline Functions)

ইনলাইন
ফাংশন হচ্ছে সি++ এর একটি শক্তিশালী কনসেপ্ট যেটা ক্লাশের সাথে অনেক
বেশী ব্যবহার করা হয়। একটি ইনলাইন ফাংশন সম্বলিত একটি প্রোগ্রাম কম্পাইল করার সময়,
কম্পাইল টাইমে যতবার ইনলাইন ফাংশনকে কল করা হবে, কম্পাইলার ততবার সেই ইনলাইন
ফাংশনের কোডের কপি সেই কল করা পয়েন্ট গুলোতে প্লেস করবে।

ইনলাইন
ফাংশনের ভেতর কোনো কোড পরিবর্তন করলে, পুরো প্রোগ্রামকে আবার কম্পাইল করতে হবে,
কারন কম্পাইলারকে আবার নতুন কোড সকল পয়েন্টে প্লেস করতে হবে।

ইনলাইন
ফাংশন ব্যবহার করার জন্য যেকোনো ফাংশন নামের আগে inline
কীওয়ার্ডটি বসাতে হবে এবং ফাংশনকে ব্যবহার করার আগেই ফাংশনকে
ডিফাইন করতে হবে।

একটি
ইনলাইন ফাংশন সম্বলিত প্রোগ্রামের উদাহরণ –

#include <iostream>
using namespace std;

inline int Max(int x, int y) {
    return (x > y) ? x : y;
}

int main() {
    cout << "Max (10, 20): " << Max(10, 20) << endl;
    cout << "Max (0, 10): " << Max(0, 10) << endl;
    cout << "Max (1050, 2050): " << Max(1050, 2050) << endl;
    
    return 0;
}

আউটপুট

Max (10, 20): 20
Max (0, 10): 10
Max (1050, 2050): 2050

Posts created 18

মন্তব্য করুন

আপনার ই-মেইল এ্যাড্রেস প্রকাশিত হবে না। * চিহ্নিত বিষয়গুলো আবশ্যক।

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top
Scroll Up