আমি কখন সি ++ এর কোন শ্রেণীর সদস্যদের উল্লেখ করতে বিন্দু, তীর বা ডাবল কোলন ব্যবহার করব?


243

: অন্যান্য সি-ডিরাইভড ল্যাঙ্গুয়েজ সি (জাভা বা C # এর মত) থেকে আসছে ++ এটি প্রথম খুব বিভ্রান্তিকর যে সি ++ তিনটি উপায়ে একটি বর্গ সদস্যদের পড়ুন হয়েছে এ a::b, a.bএবং a->b। আমি কখন এই অপারেটরটি ব্যবহার করব?

(দ্রষ্টব্য: এই একটি এন্ট্রি হতে বোঝানো হয় স্ট্যাক ওভারফ্লো সি ++ প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী । আপনি তারপর, এই ফর্মে একটি প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী প্রদান ধারণা সমালোচনা করতে চান, মেটা যে শুরু এই সব পোস্টিং । যে কাজ করতে জায়গা হবে উত্তর সেই প্রশ্নটি সি ++ চ্যাটরুমে পর্যবেক্ষণ করা হয় , যেখানে এফএকিউ ধারণাটি প্রথম স্থানে শুরু হয়েছিল, সুতরাং আপনার উত্তরটি যারা ধারণাটি নিয়ে এসেছিল তারা খুব সম্ভবত পঠন করতে পারে।)

উত্তর:


248

তিনটি পৃথক অপারেটর সি ++ একটি শ্রেণি বা শ্রেণীর অবজেক্টের সদস্যদের অ্যাক্সেস করতে ব্যবহার করে, যথা ডাবল কোলন ::, ডট .এবং তীর ->, তিনটি পৃথক পরিস্থিতির জন্য ব্যবহৃত হয় যা সর্বদা সংজ্ঞায়িত হয়। এই বুদ্ধিমান আপনি অবিলম্বে সম্পর্কে বেশ অনেক জানেন করতে পারবেন aএবং bশুধু দিকে তাকিয়ে a::b, a.bকিংবা a->bযথাক্রমে, আপনি তাকান কোন কোডে।

  1. a::bকেবলমাত্র bশ্রেণীর সদস্য (বা নেমস্পেস) থাকলে ব্যবহৃত হয় a। অর্থাৎ, aএক্ষেত্রে সর্বদা শ্রেণীর নাম (বা নেমস্পেস) থাকবে।

  2. a.bকেবলমাত্র যদি bঅবজেক্টের সদস্য (বা কোনও জিনিসের রেফারেন্স) হয় তবে ব্যবহৃত হয় a। সুতরাং a.b, aসর্বদা একটি শ্রেণীর একটি আসল অবজেক্ট (বা কোনও জিনিসের একটি রেফারেন্স) হবে।

  3. a->bমূলত এটির জন্য একটি সংক্ষিপ্ত স্বরলিপি (*a).b। যাইহোক, ->কেবল সদস্য অ্যাক্সেস অপারেটরগুলির মধ্যেই ওভারলোড করা যায়, সুতরাং যদি aকোনও শ্রেণীর কোনও বস্তু যা ওভারলোড হয় operator->(সাধারণ ধরণের ধরণের স্মার্ট পয়েন্টার এবং পুনরাবৃত্তকারী হয়), তবে ক্লাস ডিজাইনার বাস্তবায়নে যা কিছু বোঝায় তা অর্থ। উপসংহারে: সাথে a->b, যদি aএকটি পয়েন্টার হয় bতবে পয়েন্টারটি aনির্দেশ করে এমন বস্তুর সদস্য হবে । তবে, aযদি কোনও শ্রেণীর কোনও বস্তু যা এই অপারেটরটিকে ওভারলোড করে, তবে ওভারলোডেড অপারেটর ফাংশনটি অনুরোধ operator->()করা হবে।


ছোট মুদ্রণ:

  • C ++, ধরন হিসেবে ঘোষণা class, structঅথবা union"শ্রেণী ধরনের" বিবেচনা করা হয়। সুতরাং উপরোক্ত তিনটিই বোঝায়।
  • রেফারেন্সগুলি, শব্দার্থতভাবে, অবজেক্টগুলির জন্য উপাধি হয়, সুতরাং আমার # 3 এর সাথে "বা একটি পয়েন্টারের রেফারেন্স" যুক্ত করা উচিত ছিল। তবে, আমি ভেবেছিলাম এটি সহায়কের চেয়ে আরও বিভ্রান্তিকর হবে, যেহেতু পয়েন্টার ( T*&) এর উল্লেখ খুব কমই ব্যবহৃত হয়।
  • বিন্দু এবং তীর অপারেটরগুলি বস্তুর সদস্য না হয়েও কোনও বস্তু থেকে স্থির শ্রেণীর সদস্যদের উল্লেখ করতে ব্যবহার করা যেতে পারে। (এটি উল্লেখ করার জন্য অলিকে ধন্যবাদ!)

10
সম্ভবত এটি স্পষ্ট করা উচিত .এবং ->এটি কোনও বস্তুর মাধ্যমে ক্লাস স্ট্যাটিক্স অ্যাক্সেস করতেও ব্যবহৃত হতে পারে, যদিও তারা কঠোরভাবে "বস্তুর সদস্য" নন।
অলিভার চার্লসওয়ার্থ

@ অলি: সত্যই সত্য। আমি এটিকে ছোট মুদ্রণটিতে যুক্ত করেছি, কারণ আমি মনে করি এটি মূল পাঠ্যে তালিকাভুক্ত করার পক্ষে সাধারণ এবং যথেষ্ট গুরুত্বপূর্ণ নয়।
এসবিআই

3
সম্পূর্ণতার জন্য, এটি operator*()ওভারলোড করাও যেতে পারে এবং এটি ওভারলোডের সাথে সামঞ্জস্য হতে বাধ্য করে এমন কোনও কিছুই জোর করে না operator->()! (আমি
বিটিডব্লিউকে নামিয়ে দেইনি

@ অলিচার্লসওয়ার্থ আপনি কি জানবেন যে এটি সি ++ স্ট্যান্ডার্ডে নির্দিষ্ট করা হয়েছে?
সোয়াইন

1
@ জুয়ানচোপাঞ্জা: তবে, ->ওভারলোডিং operator*এবং ব্যবহার করে আপনি শৃঙ্খলাবদ্ধ আচরণ পেতে পারেন না .। কেবল operator->ওভারলোডগুলি তা পায়।
বেন ভয়েগট

36

এসবিআই এর পয়েন্ট 3 এর বিকল্পের পরামর্শ দেওয়া

a->bকেবলমাত্র যদি aপয়েন্টার হয় তবে ব্যবহৃত হয়। এটির জন্য একটি সাধারণভাবে সংক্ষেপে হয় (*a).b, bবস্তু সদস্য aপয়েন্ট। সি ++ এ দুটি ধরণের পয়েন্টার রয়েছে, "নিয়মিত" এবং স্মার্ট পয়েন্টার। নিয়মিত পয়েন্টারগুলির জন্য যেমন A* a, সংকলক প্রয়োগ করে ->। যেমন স্মার্ট পয়েন্টারগুলির জন্য std::shared_ptr<A> a, ->শ্রেণীর সদস্য ফাংশন shared_ptr

যুক্তি: এই FAQ এর লক্ষ্য শ্রোতা স্মার্ট পয়েন্টার লিখছেন না। তাদের জানার দরকার নেই যা ->সত্যই বলা হয় operator->(), বা এটিই কেবল সদস্য অ্যাক্সেস পদ্ধতি যা ওভারলোড করা যায়।


4
আমি এর সাথে একমত হই বা না থাকুক না কেন, আমি +1বিকল্প উত্তর দেওয়ার জন্য এটিকে একটি যুক্তি দিয়েছি ।
এসবিআই

2
ওয়েল, ফর্সা হওয়ার ->জন্য স্ট্যান্ডার্ড পুনরাবৃত্তির জন্যও ওভারলোড করা হয় যা কোনও সি ++ প্রোগ্রামার শীঘ্রই দেখা উচিত, তাই বলে যে এটি কেবল পয়েন্টারগুলির জন্যই ব্যবহৃত হয় বিভ্রান্তিকর হতে পারে।
কিস্কসিরকে

@ কিস্কিরকে "সাধারণ সি ++ প্রোগ্রামারস" কেবল স্মার্ট পয়েন্টার বা পুনরাবৃত্তকারী টাইপগুলি লেখার প্রয়োজন নেই। "পয়েন্টারের মতো ডিরিফারেন্স" উভয়ের জন্যই প্রযোজ্য।
এপ্রিল কালেথ

0
#include <iostream>
#include <string>

using namespace std;

class Human {
private:
    int age;

public:
    string name;

    Human(int humanAge, string humanName) 
         : age(humanAge), name(std::move(humanName)) {}

    void DoSomething() {
        cout << age << endl;
    }

    static void DisplayAge(const Human& person) {
        cout << person.age << endl;
    }

    // ...
};

int main() {
    // Usage of Dot(.) 
    Human firstMan(13, "Jim"); // firstMan is an instance of class Human
    cout << firstMan.name << endl; // accessing member attributes
    firstMan.DoSomething(); // accessing member functions

    // Usage of Pointer Operator (->)
    Human* secondMan = new Human(24, "Tom");
    cout << secondMan->name << endl; // accessing member attributes
    secondMan->DoSomething(); // accessing member functions
    cout << (*secondMan).name << endl; // accessing member attributes
    (*secondMan).DoSomething(); // accessing member functions

    // Usage of Double Colon (::)
    Human::DisplayAge(firstMan);
    firstMan.DisplayAge(firstMan); // ok but not recommended
    secondMan->DisplayAge(firstMan); // ok but not recommended

    delete(secondMan);

    return 0;
}

উপরে কোডিং উদাহরণ থেকে আমরা দেখতে যে:
* একটি দৃষ্টান্ত (অথবা বস্তু) থেকে অ্যাক্সেস করা সদস্যদের (গুণাবলী এবং ফাংশন) ডট অপারেটর (ব্যবহার .)
* একটি বস্তু সদস্যদের একটি পয়েন্টার থেকে (গুণাবলী এবং ফাংশন) অ্যাক্সেস (বা দ্বারা নির্মিত new) পয়েন্টার অপারেটর ব্যবহার করে ( ->)
* ডাবল কোলন ( ::) ব্যবহার করে হ্যান্ডেল হিসাবে কোনও বস্তু না নিয়েই ক্লাস থেকেই স্ট্যাটিক সদস্য ফাংশনগুলি অ্যাক্সেস করা । [ দ্রষ্টব্য: আপনি স্থিতিশীল সদস্য ফাংশনটি এমন উদাহরণ থেকে অনুরোধ করতে পারেন যা .বা ->প্রস্তাবিত নয়)


@ এসবিআই তাই ভয়াবহ হা, আমি জানি এটি একরকম পুনরাবৃত্তি। সেগুলি কীভাবে ব্যবহার করতে হয় তা দেখানোর জন্য আমি কেবল একটি সুস্পষ্ট উদাহরণ দিতে চাই। এবং যেখানে আমি বলেছিলাম ->যে কেবলমাত্র সেই পয়েন্টার ব্যবহার করা যেতে পারে যা গাদাতে বরাদ্দ দেওয়া হয় new? দ্বিতীয় আইটেমের নীচে, আমি মনে করি আমি সত্যিই এটি পরিষ্কার করে দিচ্ছি যা ->পয়েন্টারের জন্য। এবং আপনি ডাউনটিভোট করার আগে আপনি className::non_static_member_function()নিজের দ্বারা সি ++ 14 দিয়ে আরও ভাল করে চেষ্টা করুন । রেফারেন্স কোনও পয়েন্টার নয়, তাই এটি ব্যবহার করতে পারে .এবং আমি আমার উত্তরে আরও স্পষ্ট করে তুলব।
হু Xixi

0

ডট অপারেটর সরাসরি সদস্য নির্বাচনের পরিস্থিতিতে ব্যবহৃত হয়

print(a.b)

এখানে, আমরা অ্যাক্সেস করছি b, যা কোনও বস্তুর প্রত্যক্ষ সদস্য a। সুতরাং, প্রাথমিকভাবে, aএকটি অবজেক্ট এবং এর bসদস্য (ফাংশন / ভেরিয়েবল ইত্যাদি) a


তীর অপারেটর অপ্রত্যক্ষ সদস্য নির্বাচনের পরিস্থিতিতে ব্যবহৃত হয়

print(a->b)

এখানে, আমরা অ্যাক্সেস করছি bযা অবজেক্টের সদস্য, এটি দ্বারা নির্দেশিত a। এটি সংক্ষিপ্তরূপে (*a).bএবং তাই এখানে, aমূলত কোনও বস্তুর পয়েন্টার এবং object বস্তুর bসদস্য a


ডাবল কোলন (স্কোপ) অপারেটর নামের স্থান সম্পর্কিত সরাসরি সদস্য নির্বাচনের পরিস্থিতিতে ব্যবহৃত হয়

print(a::b)

এখানে, আমরা অ্যাক্সেস করছি bযা ক্লাস / নেমস্পেসের সদস্য ao সুতরাং, প্রাথমিকভাবে, aএকটি শ্রেণি / নেমস্পেস এবং এর bসদস্য (ফাংশন / ভেরিয়েবল ইত্যাদি) a

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.