'কনস্ট' এর অর্থ কোনও শ্রেণির ঘোষণায় শেষ হয়?


726

constএ জাতীয় ঘোষণার অর্থ কী ? constআমাকে বিভ্রান্ত।

class foobar
{
  public:
     operator int () const;
     const char* foo() const;
};

উত্তর:


950

আপনি যখন constকোনও পদ্ধতিতে কীওয়ার্ডটি যুক্ত করবেন তখন thisপয়েন্টারটি মূলত constআপত্তি করার জন্য একটি পয়েন্টার হয়ে যাবে এবং আপনি কোনও সদস্যের ডেটা পরিবর্তন করতে পারবেন না। (আপনি যদি না ব্যবহার করেন তবে তারপরে mutableআরও কিছু)।

constশব্দ ফাংশন স্বাক্ষর যার অর্থ হল যে আপনি দুটি একই পদ্ধতি, এক যা যখন বস্তুর বলা হয় বাস্তবায়ন করতে পারে অংশ const, এবং এক যে নয়।

#include <iostream>

class MyClass
{
private:
    int counter;
public:
    void Foo()
    { 
        std::cout << "Foo" << std::endl;    
    }

    void Foo() const
    {
        std::cout << "Foo const" << std::endl;
    }

};

int main()
{
    MyClass cc;
    const MyClass& ccc = cc;
    cc.Foo();
    ccc.Foo();
}

এই আউটপুট হবে

Foo
Foo const

নন-কনস্ট্যান্ড পদ্ধতিতে আপনি উদাহরণ সদস্যদের পরিবর্তন করতে পারেন, যা আপনি constসংস্করণে করতে পারবেন না । উপরের উদাহরণে পদ্ধতি ঘোষণাকে নীচের কোডে পরিবর্তন করলে আপনি কিছু ত্রুটি পাবেন।

    void Foo()
    {
        counter++; //this works
        std::cout << "Foo" << std::endl;    
    }

    void Foo() const
    {
        counter++; //this will not compile
        std::cout << "Foo const" << std::endl;
    }

এটি সম্পূর্ণ সত্য নয়, কারণ আপনি কোনও সদস্যকে চিহ্নিত করতে পারেন mutableএবং কোনও constপদ্ধতি তারপরে পরিবর্তন করতে পারে। এটি বেশিরভাগ অভ্যন্তরীণ কাউন্টার এবং স্টাফের জন্য ব্যবহৃত হয়। তার জন্য সমাধানটি নীচের কোডটি হবে।

#include <iostream>

class MyClass
{
private:
    mutable int counter;
public:

    MyClass() : counter(0) {}

    void Foo()
    {
        counter++;
        std::cout << "Foo" << std::endl;    
    }

    void Foo() const
    {
        counter++;    // This works because counter is `mutable`
        std::cout << "Foo const" << std::endl;
    }

    int GetInvocations() const
    {
        return counter;
    }
};

int main(void)
{
    MyClass cc;
    const MyClass& ccc = cc;
    cc.Foo();
    ccc.Foo();
    std::cout << "Foo has been invoked " << ccc.GetInvocations() << " times" << std::endl;
}

যা আউটপুট হবে

Foo
Foo const
Foo has been invoked 2 times

186

কনস্টের অর্থ হল যে পদ্ধতিটি শ্রেণীর কোনও সদস্যকে পরিবর্তন না করার প্রতিশ্রুতি দেয়। আপনি অবজেক্টের সদস্যদের যে এত চিহ্নযুক্ত তা কার্যকর করতে সক্ষম হবেন, এমনকি যদি বস্তুটি নিজেই চিহ্নিত ছিল const:

const foobar fb;
fb.foo();

আইনী হবে।

দেখুন কত এবং যা "const" C ++ ব্যবহার হয়? আরও তথ্যের জন্য.


47

constকোয়ালিফায়ার মানে যে কোনো পদ্ধতি মূল্যের ওপর বলা যেতে পারে যে foobar। পার্থক্য তখনই আসে যখন আপনি কনস্ট কনজেক্টে নন-কনস্ট্যান্ড পদ্ধতি কল করার বিষয়টি বিবেচনা করেন। আপনার foobarধরণের নিম্নলিখিত অতিরিক্ত পদ্ধতির ঘোষণা ছিল কিনা তা বিবেচনা করুন :

class foobar {
  ...
  const char* bar();
}

পদ্ধতিটি bar()নন-কনস্ট্যান্ড এবং শুধুমাত্র অ-কনস্ট্যান্ট মান থেকে অ্যাক্সেস করা যায়।

void func1(const foobar& fb1, foobar& fb2) {
  const char* v1 = fb1.bar();  // won't compile
  const char* v2 = fb2.bar();  // works
}

constযদিও এর পিছনে ধারণাটি এমন পদ্ধতিগুলি চিহ্নিত করা যা শ্রেণীর অভ্যন্তরীণ অবস্থার কোনও পরিবর্তন ঘটাবে না। এটি একটি শক্তিশালী ধারণা তবে বাস্তবে এটি C ++ এ কার্যকর করা যায় না। এটি গ্যারান্টি অপেক্ষা আরও একটি প্রতিশ্রুতি। এবং একটি যা প্রায়শই ভেঙে যায় এবং সহজেই ভেঙে যায়।

foobar& fbNonConst = const_cast<foobar&>(fb1);

3
আমি ভেবেছিলাম উত্তরটি অন্য কনস্টের পদ্ধতি সম্পর্কে এবং কনস্টের অবজেক্ট সম্পর্কে নয়।
মাইকোলা গোলুয়েভ

" constযদিও এর পেছনের ধারণাটি এমন পদ্ধতিগুলি চিহ্নিত করা যা শ্রেণীর অভ্যন্তরীণ অবস্থার পরিবর্তন করবে না " এর জন্য ধন্যবাদ । সত্যিই আমি যা খুঁজছিলাম।
কোভাক

1
@ জারেড পার এর অর্থ কি এই যে কোনও সদস্যের ফাংশন কেবলমাত্র পঠনযোগ্য অপারেশনের প্রতিনিধিত্ব করে তা চিহ্নিত করা উচিত const?
কোভাক

26

এই কনস্টের অর্থ হ'ল পদ্ধতিটি 'কনস্ট' সহ অভ্যন্তরীণ ডেটা পরিবর্তন করলে সংকলক ত্রুটি করবে।

class A
{
public:
    A():member_()
    {
    }

    int hashGetter() const
    {
        state_ = 1;
        return member_;
    }
    int goodGetter() const
    {
        return member_;
    }
    int getter() const
    {
        //member_ = 2; // error
        return member_;
    }
    int badGetter()
    {
        return member_;
    }
private:
    mutable int state_;
    int member_;
};

পরীক্ষা

int main()
{
    const A a1;
    a1.badGetter(); // doesn't work
    a1.goodGetter(); // works
    a1.hashGetter(); // works

    A a2;
    a2.badGetter(); // works
    a2.goodGetter(); // works
    a2.hashGetter(); // works
}

পড়ুন এই আরও তথ্যের জন্য


1
constসদস্য ফাংশন সম্পর্কিত একটি প্রশ্ন যা মিউটেবলের কথা উল্লেখ করে না এটি সর্বোপরি অসম্পূর্ণ।
IInspectable

13

ব্লেয়ারের উত্তর চিহ্ন রয়েছে।

তবে মনে রাখবেন যে একটি mutableযোগ্যতা রয়েছে যা ক্লাসের ডেটা সদস্যদের সাথে যুক্ত হতে পারে। চিহ্নিত চিহ্নিত কোনও সদস্য চুক্তি লঙ্ঘন না করে কোনও পদ্ধতিতে সংশোধন করা যেতে পারে ।constconst

আপনি যদি এই পদ্ধতির "লজিক্যাল" দৃness়তাটিকে প্রভাবিত না করেন তবে কোনও নির্দিষ্ট পদ্ধতিটি কতবার বলা হয় তা মনে রাখার জন্য যদি আপনি কোনও অবজেক্ট চান তবে আপনি এটি (উদাহরণস্বরূপ) ব্যবহার করতে চাইতে পারেন।


10

একটি const সদস্য ফাংশন মানে মধ্যে সি ++ সাধারণ জ্ঞান: আবশ্যিক অন্তর্বর্তী প্রোগ্রামিং সুস্পষ্ট ব্যাখ্যা দেয়:

দশম শ্রেণির অ-কনস্ট্যান্ড সদস্য ফাংশনে এই পয়েন্টারটির ধরণটি হ'ল এক্স * কনস্ট্রেট। এটি হ'ল এটি একটি অ-ধ্রুব এক্স এর একটি ধ্রুবক পয়েন্টার (কনস্ট পয়েন্টার এবং পয়েন্টার টু কনস্ট [7, 21] দেখুন)। কারণ যে বস্তুকে এটি উল্লেখ করা হয় তা কনস্ট নয়, এটি পরিবর্তন করা যেতে পারে। দশম শ্রেণির কনস্টের সদস্য ফাংশনে এর ধরণটি হ'ল কনস্ট এক্স * কনস্ট্রেট। এটি হ'ল এটি একটি ধ্রুবক এক্সের একটি ধ্রুবক পয়েন্টার Because কারণ এটি যে বস্তুকে বোঝায় এটি কনস্ট, এটি সংশোধন করা যায় না। কনস্ট্যান্ড এবং নন-কনস্ট্যান্ড সদস্য ফাংশনের মধ্যে এটিই পার্থক্য।

সুতরাং আপনার কোডে:

class foobar
{
  public:
     operator int () const;
     const char* foo() const;
};

আপনি এটি হিসাবে এটি ভাবতে পারেন:

class foobar
{
  public:
     operator int (const foobar * const this) const;
     const char* foo(const foobar * const this) const;
};

thisনা const। এটি সংশোধন করা যায় না তার কারণ এটি একটি মূল্য।
ব্রায়ান

7

আপনি যখন constপদ্ধতিটির স্বাক্ষর ব্যবহার করেন (যেমন আপনার বলেছেন const char* foo() const;:) আপনি কম্পাইলারকে বলছেন যে স্মৃতি দ্বারা নির্দেশিত thisএই পদ্ধতিটি (যা fooএখানে রয়েছে) দ্বারা পরিবর্তন করা যায় না ।


6

আমি নিম্নলিখিত বিষয় যোগ করতে চাই।

আপনি এটি একটি এবং করতে পারেনconst &const &&

সুতরাং,

struct s{
    void val1() const {
     // *this is const here. Hence this function cannot modify any member of *this
    }
    void val2() const & {
    // *this is const& here
    }
    void val3() const && {
    // The object calling this function should be const rvalue only.
    }
    void val4() && {
    // The object calling this function should be rvalue reference only.
    }

};

int main(){
  s a;
  a.val1(); //okay
  a.val2(); //okay
  // a.val3() not okay, a is not rvalue will be okay if called like
  std::move(a).val3(); // okay, move makes it a rvalue
}

উত্তর উন্নত নির্দ্বিধায়। আমি কোন বিশেষজ্ঞ নই


1
*thisসদস্য ফাংশনটি মূল্য-রেফ-কোয়ালিফাইড থাকলেও এবং মূল্যকে ডেকে আনা হলেও সর্বদা একটি মূল্যবান। উদাহরণ
হলিব্ল্যাকগেট

1
হ্যাঁ, তাহলে আমার বর্তমান উত্তরটি কীভাবে উন্নত করা উচিত?
কোডার3101

আমার অর্থ ব্লকের মন্তব্যে কী লিখতে হবে, যা আচরণের ন্যায্যতা দেয়
কোডার 3101

আপডেট করা হয়েছে। তা কি ঠিক আছে?
কোডার3101

2

Const শব্দ ফাংশন ঘোষণা নির্দিষ্ট করে যে এটি একটি হল সঙ্গে ব্যবহার const সদস্য ফাংশন এবং এটি হবে পরিবর্তন করতে পারবেন না বস্তুর তথ্য সদস্যরা।


1

https://isocpp.org/wiki/faq/const-correctness#const-member-fns

" constসদস্য ফাংশন" কী?

একটি সদস্য ফাংশন যা তার অবজেক্টটি পরীক্ষা করে (পরিবর্তে পরিবর্তিত করে)।

একজন constসদস্য ফাংশন একটি দ্বারা নির্দেশিত হয় constমাত্র সদস্য ফাংশনের প্যারামিটার তালিকার পরে প্রত্যয়। constপ্রত্যয় সহ সদস্য ফাংশনগুলিকে "কনস্ট সদস্য ফাংশন" বা "পরিদর্শক" বলা হয়। constপ্রত্যয়বিহীন সদস্য ফাংশনগুলিকে "নন-কনস্ট্যান্ড সদস্য ফাংশন" বা "মিউটর" বলা হয়।

class Fred {
public:
  void inspect() const;   // This member promises NOT to change *this
  void mutate();          // This member function might change *this
};
void userCode(Fred& changeable, const Fred& unchangeable)
{
  changeable.inspect();   // Okay: doesn't change a changeable object
  changeable.mutate();    // Okay: changes a changeable object
  unchangeable.inspect(); // Okay: doesn't change an unchangeable object
  unchangeable.mutate();  // ERROR: attempt to change unchangeable object
}

কল unchangeable.mutate()করার চেষ্টাটি সংকলনের সময় ধরা পড়া একটি ত্রুটি। এর জন্য কোনও রানটাইম স্পেস বা স্পিড পেনাল্টি নেই constএবং রানটাইমটিতে এটি পরীক্ষা করার জন্য আপনার টেস্ট-কেস লেখার দরকার নেই।

সদস্য ফাংশনটির পিছনে constথাকা inspect()অর্থ এই পদ্ধতিতে ব্যবহার করা উচিত যে পদ্ধতিটি বস্তুর বিমূর্ত (ক্লায়েন্ট-দৃশ্যমান) অবস্থাকে পরিবর্তন করবে না । এটি বলার চেয়ে কিছুটা আলাদা যে পদ্ধতিটি বস্তুর কাঠামোর "কাঁচা বিট" পরিবর্তন করবে না। সি ++ সংকলককে "বিটওয়াইজ" ব্যাখ্যাটি গ্রহণ করার অনুমতি দেওয়া হয় না যদি না তারা এলিয়াসিং সমস্যাটি সমাধান করতে পারে, যা সাধারণত সমাধান করা যায় না (যেমন, একটি অ-কনস্ট্যান্ট ওরফে উপস্থিত থাকতে পারে যা বস্তুর অবস্থার পরিবর্তন করতে পারে)। এই এলিয়াসিং ইস্যু থেকে আরেকটি গুরুত্বপূর্ণ (গুরুত্বপূর্ণ) অন্তর্দৃষ্টি: পয়েন্টার-টু-কনস্টের সাথে কোনও বস্তুর দিকে ইঙ্গিত করা গ্যারান্টি দেয় না যে অবজেক্টটি পরিবর্তন হবে না; এটি কেবল প্রতিশ্রুতি দেয় যে বস্তুটি সেই পয়েন্টারের মাধ্যমে পরিবর্তন হবে না ।

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