কনস্ট রেফ অপরিশোধিত আচরণ করে একটি নতুন নির্মিত বস্তু ক্যাপচার করছে


11

নিম্নলিখিত (স্বীকৃত উদাহরণ) ঠিক আছে বা এটি অপরিবর্তিত আচরণ:

// undefined behavior?
const auto& c = SomeClass{};

// use c in code later
const auto& v = c.GetSomeVariable();

উত্তর:


12

এটা নিরাপদ. কনস্ট রেফার অস্থায়ী জীবনকালকে দীর্ঘায়িত করে। সুযোগটি কনস্ট রেফার স্কোপ হবে।

দ্য জীবদ্দশায় একটি অস্থায়ী বস্তুর (সি ++ যেহেতু 11) একটি const lvalue রেফারেন্স অথবা একটি rvalue রেফারেন্স থেকে বাঁধাই দ্বারা বর্ধিত করা যেতে পারে, দেখতে রেফারেন্স আরম্ভের বিস্তারিত জানার জন্য।

যখনই কোনও রেফারেন্স কোনও অস্থায়ী বা তার একটি সাবওবজেক্টের সাথে আবদ্ধ থাকে, নীচের সাথে অস্থায়ীটির জীবনকালটি রেফারেন্সের আজীবনের সাথে মিলে যায় ব্যতিক্রমগুলি :

  • কোনও রিটার্ন স্টেটমেন্টে কোনও ফাংশনের রিটার্ন মানের সাথে আবদ্ধ অস্থায়ী প্রসারিত হয় না: এটি রিটার্ন এক্সপ্রেশন শেষে অবিলম্বে ধ্বংস হয়। এই জাতীয় ফাংশন সর্বদা একটি জটলা রেফারেন্স দেয়।
  • কনস্ট্রাক্টর ইনিশিয়ালাইজার তালিকার একটি রেফারেন্স সদস্যের সাথে অস্থায়ীভাবে আবদ্ধ থাকা কেবল অবধি অবধি উপস্থিত থাকে না যতক্ষণ না অবজেক্টের অস্তিত্ব থাকে। (দ্রষ্টব্য: এই জাতীয় সূচনাটি ডিআর 1696 হিসাবে খারাপ-গঠিত)।
  • কোনও ফাংশন কলটিতে একটি রেফারেন্স প্যারামিটারের সাথে আবদ্ধ অস্থায়ী উপস্থিত থাকে সেই ফাংশন কলযুক্ত পূর্ণ এক্সপ্রেশনটির শেষ অবধি: যদি ফাংশনটি কোনও রেফারেন্স দেয়, যা সম্পূর্ণ এক্সপ্রেশনটিকে বহির্মুখী করে তোলে, এটি একটি জটলা রেফারেন্স হয়ে যায়।
  • নতুন-এক্সপ্রেশনটিতে ব্যবহৃত ইনিশিয়ালাইজারে একটি রেফারেন্সের সাথে সাময়িকভাবে আবদ্ধ থাকা সেই নতুন-এক্সপ্রেশন যুক্ত পূর্ণ এক্সপ্রেশনটির শেষ অবধি উপস্থিত থাকে, যতক্ষণ না আদ্যক্ষর অবজেক্ট হিসাবে দীর্ঘ নয়। যদি সূচনাযুক্ত বস্তু সম্পূর্ণ এক্সপ্রেশনকে আউটলাইভ করে, তবে এর রেফারেন্স সদস্যটি ঝুঁকির রেফারেন্সে পরিণত হয়।
  • সূচনা-প্রারম্ভিক সিনট্যাক্স (বন্ধনীগুলি) এর বিপরীতে ডাইরেক্ট-ইনিশায়ালাইজেশন সিনট্যাক্স (বন্ধনীগুলি) ব্যবহার করে ইনিশিয়ালাইজারযুক্ত সম্পূর্ণ এক্সপ্রেশনের শেষ অবধি উপস্থিত থাকা সামগ্রিক সূত্রের রেফারেন্স উপাদানটিতে একটি অস্থায়ী আবদ্ধ থাকে। struct A { int&& r; }; A a1{7}; // OK, lifetime is extended A a2(7); // well-formed, but dangling reference

সাধারণভাবে, একটি অস্থায়ী জীবনকাল "" এটি পাস করে "আরও বাড়ানো যায় না: একটি দ্বিতীয় রেফারেন্স, যা অস্থায়ীভাবে আবদ্ধ ছিল সেই রেফারেন্স থেকে আরম্ভ করা তার জীবনকালকে প্রভাবিত করে না।

যেমন @ কনরাড রুডল্ফ নির্দেশ করেছেন (এবং উপরের শেষ অনুচ্ছেদটি দেখুন):

"যদি c.GetSomeVariable()কোনও স্থানীয় অবজেক্টের কোনও রেফারেন্স বা কোনও রেফারেন্স দেয় যে এটি নিজেই কিছু বস্তুর আজীবন প্রসারিত করে, আজীবন এক্সটেনশনটি লাথি দেয় না"


1
আপনার সেই উক্তির উত্স উদ্ধৃত করা উচিত।
অরব্বিটের হালকাত্বের রেস

@ লাইটনেসেসেস উইথমোনিকা করেছেন। আমি আরও ভাল পাঠ খুঁজছিলাম
31:53

2
এটি আখ্যায়িত করা ভাল হবে যে এটি কেবল মানগুলির ক্ষেত্রেই সত্য । তাহলে c.GetSomeVariable()আয় একটি রেফারেন্স একটি স্থানীয় বস্তু বা একটি রেফারেন্স এটি নিজে কিছু বস্তু এর জীবদ্দশায় ব্যাপ্ত যে, জীবদ্দশায় এক্সটেনশানটি কী না এ পদাঘাত।
কনরাড রুডলফ

@ কনরাড রুডলফ ধন্যবাদ! আমিও ব্যতিক্রম যুক্ত করেছি।
বিস্মৃত

4

জীবনকাল বর্ধনের জন্য এখানে কোনও সমস্যা হওয়া উচিত না । নবনির্মিত অবজেক্টটি রেফারেন্সের সুযোগ ছাড়াই অবধি বেঁচে থাকবে।


3

হ্যাঁ এটি পুরোপুরি নিরাপদ: একটি constরেফারেন্সের জন্য বাধ্যতামূলকভাবে অস্থায়ী জীবনকাল সেই রেফারেন্সের পরিধি পর্যন্ত প্রসারিত।

মনে রাখবেন যে আচরণটি যদিও সক্রিয় নয়। উদাহরণস্বরূপ, সাথে

const auto& cc = []{
    const auto& c = SomeClass{};
    return c;
}();

cc dangles।


2

এটি নিরাপদ।

[class.temporary]/5: তিনটি প্রসঙ্গ রয়েছে যেখানে সম্পূর্ণ-এক্সপ্রেশনটির শেষের চেয়ে পৃথক স্থানে অস্থায়ী অধ্যায়গুলি ধ্বংস হয় । [..]

[class.temporary]/6: তৃতীয় প্রসঙ্গটি হল যখন কোনও রেফারেন্স কোনও অস্থায়ী বস্তুর সাথে আবদ্ধ থাকে। অস্থায়ী বস্তুর রেফারেন্স আবদ্ধ হয় বা অস্থায়ী বস্তুর একটি subobject যা রেফারেন্স আবদ্ধ হয় সম্পূর্ণ বস্তুর যে রেফারেন্স সারা জীবনের জন্য থেকে যায় যদি glvalue যা রেফারেন্স নিম্নলিখিত একজনের কাছ থেকে প্রাপ্ত হয়েছিল আবদ্ধ হয় : [এখানে প্রচুর জিনিস]


1

এই নির্দিষ্ট ক্ষেত্রে এটি নিরাপদ। তবে নোট করুন যে সমস্ত অস্থায়ী সংস্থাগুলি রেফারেন্স দ্বারা ক্যাপচার করা নিরাপদ নয় ... উদাহরণস্বরূপ

#include <stdio.h>

struct Foo {
    int member;

    Foo() : member(0) {
        printf("Constructor\n");
    }

    ~Foo() {
        printf("Destructor\n");
    }

    const Foo& method() const {
        return *this;
    }
};

int main() {
    {
        const Foo& x = Foo{};        // safe
        printf("here!\n");
    }
    {
        const int& y = Foo{}.member; // safe too (special rule for this)
        printf("here (2)!\n");
    }
    {
        const Foo& z = Foo{}.method(); // NOT safe
        printf("here (3)!\n");
    }
    return 0;
}

এর জন্য প্রাপ্ত রেফারেন্সটি ব্যবহার zকরা নিরাপদ নয় কারণ printfবিবৃতিতে পৌঁছানোর আগে অস্থায়ী উদাহরণটি সম্পূর্ণ অভিব্যক্তির শেষে ধ্বংস হয়ে যাবে । আউটপুট হল:

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