অর্থ = ফাংশন ঘোষণার পরে মুছুন


242
class my_class
{
    ...
    my_class(my_class const &) = delete;
    ...
};

= deleteসেই প্রসঙ্গে মানে কী ?

অন্য কোন "সংশোধনকারীদের" (ব্যতীত অন্য হয় = 0এবং = delete)?


23
@ ব্লিনডি এটি সি ++ 0x এর মধ্যে স্ট্যান্ডার্ড হবে, শীঘ্রই।
কনরাড রুডল্ফ

1
আমি সংশোধন করে দাঁড়িয়েছি, আমি এই সি ++ 0x বৈশিষ্ট্যটি মিস করেছি। আমি ভাবছিলাম এটি #defineএকটি লা কিউটি যা 0 তে মূল্যায়ন করে এবং তারপরে একটি লুকানো ফাংশন বা কিছু ঘোষণা করে।
অন্ধ

আমি একটি 'অক্ষম' কীওয়ার্ডের একটি স্মৃতি পেয়েছি যার অর্থ একই বা অনুরূপ। আমি কি এটি কল্পনা করছি? বা তাদের মধ্যে একটি সূক্ষ্ম পার্থক্য আছে?
স্টিয়ার্ট

উত্তর:


201

একটি ফাংশন মোছা একটি সি ++ 11 বৈশিষ্ট্য :

"অনুলিপি নিষিদ্ধ" এর সাধারণ রীতিটি এখন সরাসরি প্রকাশ করা যেতে পারে:

class X {
    // ...
    X& operator=(const X&) = delete;  // Disallow copying
    X(const X&) = delete;
};

[...]

"মুছে ফেলুন" যেকোন ক্রিয়াকলাপের জন্য ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, আমরা এটির মতো অনাকাঙ্ক্ষিত রূপান্তরটি দূর করতে পারি:

struct Z {
    // ...

    Z(long long);     // can initialize with an long long         
    Z(long) = delete; // but not anything less
};

3
"অনুলিপি" নিষিদ্ধ করা সনাতন পদ্ধতিটি কি কেবল অনুলিপি-অন্বেষণকারী এবং অপারেটর = "ব্যক্তিগত" করার জন্য নয়? এটি আরও কিছুটা এগিয়ে যায় এবং সংযোজকটিকে এমনকি ফাংশনগুলি তৈরি না করার নির্দেশ দেয়। যদি তারা উভয় প্রাইভেট এবং = মোছা হয় তবে দ্বিগুণ-নিষিদ্ধ কী অনুলিপি করছেন?
রেব কেবিন

8
@ রিব, =deleteএমন privateপদ্ধতিগুলি (যেমন ক্লাস এবং তার বন্ধুদের মধ্যে) দেখতে পারে এমন প্রসঙ্গ থেকে এমনকি পদ্ধতিটিকে অ্যাক্সেসযোগ্য করে তোলে । আপনি কোডটি পড়ার সময় এটি কোনও অনিশ্চয়তা দূর করে। @ প্রসূন, এই দ্বিতীয় উদাহরণটি এখনও কেবল নির্মাণকারীদের মুছে ফেলছে - operator long ()উদাহরণস্বরূপ মুছে ফেলা দেখতে ভাল লাগবে ।
টবি স্পিড

2
@ রেব.ক্যাবিন ব্যবহার = deleteকরা privateবা অন্যান্য অনুরূপ প্রক্রিয়াগুলির চেয়ে ভাল কারণ সাধারণত আপনি চাইছেন যে নিষিদ্ধ ফাংশনটি দৃশ্যমানভাবে ঘোষণা করা হবে এবং ওভারলোড রেজোলিউশন ইত্যাদির জন্য বিবেচনা করা উচিত, যাতে এটি যত তাড়াতাড়ি সম্ভব ব্যর্থ হয় এবং ব্যবহারকারীর কাছে পরিষ্কার ত্রুটি সরবরাহ করে। ঘোষণাকে "আড়াল করা" জড়িত এমন কোনও সমাধান এই প্রভাবকে হ্রাস করে।
লুশেনকো

1
অনুলিপি নির্মাণকারীকে সর্বজনীন করার এবং মুছার কীওয়ার্ডটি প্রয়োগ করার কোনও বিশেষ কারণ আছে? কনস্ট্রাক্টরকে বেসরকারী রেখে কীওয়ার্ডটি প্রয়োগ করবেন না কেন?
দোহন জো

81
  1. = 0এর অর্থ হ'ল কোনও ফাংশন খাঁটি ভার্চুয়াল এবং আপনি এই শ্রেণি থেকে কোনও বস্তু ইনস্ট্যান্ট করতে পারবেন না। আপনার এটি থেকে উদ্ভূত হওয়া এবং এই পদ্ধতিটি প্রয়োগ করা দরকার
  2. = deleteএর অর্থ হ'ল সংকলকটি আপনার জন্য সেই নির্মাণকারী তৈরি করবে না। এএফআইএইকি এটি কেবল অনুলিপি নির্মাণকারী এবং অ্যাসাইনমেন্ট অপারেটরে অনুমোদিত। তবে আসন্ন স্ট্যান্ডার্ডে আমি খুব একটা ভাল না।

4
=deleteসিনট্যাক্সের আরও কিছু ব্যবহার রয়েছে । উদাহরণস্বরূপ আপনি কলটির সাথে সংঘটিত হতে পারে এমন কিছু ধরণের রূপান্তরিত রূপান্তরকে সুস্পষ্টভাবে অস্বীকার করার জন্য এটি ব্যবহার করতে পারেন। এর জন্য আপনি কেবল ওভারলোডেড ফাংশনগুলি মুছুন। আরও তথ্যের জন্য উইকিপিডিয়া পৃষ্ঠাটি সি ++ 0x এ দেখুন।
লাইকাও

আমি কিছু খুঁজে পাওয়ার সাথে সাথে এটি করব। অনুমান করার সময়টি সি ++ 0
এক্স

হ্যাঁ, সি ++ 0x শিলা। আমি জিসিসি 4.5 ++ বেশি সাধারণ হওয়ার জন্য অপেক্ষা করতে পারি না, তাই আমি ল্যাম্বডাস ব্যবহার শুরু করতে পারি।
লাইকাও

5
এর বিবরণ = deleteসম্পূর্ণ সঠিক নয়। = deleteযে কোনও ফাংশনের জন্য ব্যবহার করা যেতে পারে, সেক্ষেত্রে এটি স্পষ্টভাবে মুছে ফেলা হিসাবে চিহ্নিত এবং কোনও সংকলক ত্রুটির ফলে ব্যবহারের ফলাফল। বিশেষ সদস্য ক্রিয়াকলাপগুলির জন্য, এর অর্থ এটির অর্থও বিশেষ করে যে তারা তখন আপনার জন্য সংকলক তৈরি করে না, তবে এটি কেবল মুছে ফেলার ফলস্বরূপ, এবং যা = deleteসত্য তা নয়।
মাইক্রোভাইরাস

28

দ্য সি ++ প্রোগ্রামিং ল্যাঙ্গুয়েজের এই অংশটি [৪ র্থ সংস্করণ] - বাজার্ন স্ট্রস্ট্রপ বইটি ব্যবহার করার পিছনে আসল উদ্দেশ্য সম্পর্কে আলোচনা করেছে =delete:

3.3.4 অপারেশন দমন

শ্রেণিবিন্যাসের ডিফল্ট অনুলিপি বা শ্রেণীর জন্য সরানো সাধারণত বিপর্যয় : একটি বেসকে কেবলমাত্র একটি পয়েন্টার দেওয়া হয়, আমরা কেবল জানি না যে উত্পন্ন শ্রেণীর সদস্যরা কী আছে, তাই আমরা কীভাবে তাদের অনুলিপি করতে পারি তা আমরা জানি না । সুতরাং, সর্বোত্তম কাজটি হ'ল সাধারণত ডিফল্ট অনুলিপি মুছে ফেলা এবং অপারেশন সরিয়ে নেওয়া, অর্থাৎ এই দুটি অপারেশনের ডিফল্ট সংজ্ঞাগুলি মুছে ফেলা:

class Shape {
public:
  Shape(const Shape&) =delete; // no copy operations
  Shape& operator=(const Shape&) =delete;

  Shape(Shape&&) =delete; // no move operations
  Shape& operator=(Shape&&) =delete;
  ˜Shape();
    // ...
};

এখন একটি শেপ অনুলিপি করার চেষ্টা কম্পাইলার দ্বারা ধরা পড়বে।

=deleteপ্রক্রিয়া যে সাধারণ হয়, এটা কোনো অপারেশন দমন করতে ব্যবহার করা যেতে পারে


10

অন্য কোন "সংশোধনকারীদের" (ব্যতীত অন্য হয় = 0এবং = delete)?

যেহেতু এটি উপস্থিত হিসাবে অন্য কেউ এই প্রশ্নের উত্তর দেয় না, তাই আমারও উল্লেখ করা উচিত যে রয়েছে =default

https://docs.microsoft.com/en-us/cpp/cpp/explicitly-defaulted-and-deleted-functions#explicitly-defaulted-functions


1
ইয়াহ, আমি এটি খুঁজছিলাম
আর্দেন্ট কোডার

5

কোডিং মানগুলির সাথে আমি কাজ করেছি বেশিরভাগ শ্রেণীর ঘোষণার জন্য নিম্নলিখিতটি ছিল।

//  coding standard: disallow when not used
T(void)                  = delete; // default ctor    (1)
~T(void)                 = delete; // default dtor    (2)
T(const T&)              = delete; // copy ctor       (3)
T(const T&&)             = delete; // move ctor       (4)
T& operator= (const T&)  = delete; // copy assignment (5)
T& operator= (const T&&) = delete; // move assignment (6)

আপনি যদি এই 6 টির কোনও ব্যবহার করেন তবে আপনি কেবল সম্পর্কিত লাইনটি মন্তব্য করেন।

উদাহরণ: ক্লাস ফিজবাসের জন্য কেবলমাত্র ডটর প্রয়োজন, এবং অন্য 5 টি ব্যবহার করবেন না।

//  coding standard: disallow when not used
FizzBuzz(void)                         = delete; // default ctor (1)
// ~FizzBuzz(void);                              // dtor         (2)
FizzBuzz(const FizzBuzz&)              = delete; // copy ctor    (3)
FizzBuzz& operator= (const FizzBuzz&)  = delete; // copy assig   (4)
FizzBuzz(const FizzBuzz&&)             = delete; // move ctor    (5)
FizzBuzz& operator= (const FizzBuzz&&) = delete; // move assign  (6)

আমরা এখানে কেবল 1 টি মন্তব্য করি এবং এর বাস্তবায়ন ইনস্টল করি যেখানে অন্যথায় (সম্ভবত যেখানে কোডিং স্ট্যান্ডার্ডটি পরামর্শ দেয়)। অন্যান্য 5 টি (6 এর) মুছে ফেলা নিষিদ্ধ।

আপনি বিভিন্ন আকারের মানগুলির অন্তর্নিহিত প্রচারগুলি অস্বীকার করতে '= মুছুন' ব্যবহার করতে পারেন ... উদাহরণস্বরূপ

// disallow implicit promotions 
template <class T> operator T(void)              = delete;
template <class T> Vuint64& operator=  (const T) = delete;
template <class T> Vuint64& operator|= (const T) = delete;
template <class T> Vuint64& operator&= (const T) = delete;

3

= deleteসি ++ 11 এ পরিচিত একটি বৈশিষ্ট্য। হিসাবে =deleteএটি যে ফাংশন কল করতে অনুমতি দেওয়া হবে না।

বিস্তারিত.

ধরুন একটা ক্লাসে।

Class ABC{
 Int d;
 Public:
  ABC& operator= (const ABC& obj) =delete
  {

  }
};

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


2

নতুন সি ++ 0 এক্স স্ট্যান্ডার্ড। N3242 কার্যনির্বাহী খসড়াটিতে অনুচ্ছেদ 8.4.3 দেখুন


ওহ, সেই খসড়াটি পুরানো। এখানে সর্বশেষ (3 শে এপ্রিল ২০১১ হিসাবে): ওপেন- std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf
টনি কে

ধন্যবাদ এবং আপডেট লিংক। বর্তমান খসড়াটি পেতে খুব সহায়ক। পুরানো খসড়াটিতে এমনকি রেফারেন্স করা বিভাগ / সামগ্রীটি সঠিক ছিল তাই আমি নীচের ভোটটি বুঝতে পারি না।
দুপুরে

1

একটি মুছে ফেলা ফাংশন অন্তর্নিহিত ইনলাইন

(বিদ্যমান উত্তরের সাথে সংযোজন)

... এবং মুছে ফেলা ফাংশনটির প্রথম ঘোষণাটি হবে (ফাংশন টেম্পলেটগুলির স্পষ্ট বিশেষায়ন মুছে ফেলা ব্যতীত - মুছা বিশেষকরণের প্রথম ঘোষণার সময় হওয়া উচিত), যার অর্থ আপনি কোনও কার্য ঘোষণা করতে পারবেন না এবং পরে এটি মুছবেন, বলুন, একটি অনুবাদ ইউনিট এর সংজ্ঞা স্থানীয়।

Citing [dcl.fct.def.delete] / 4 :

একটি মুছে ফেলা ফাংশন অন্তর্নিহিত ইনলাইন। ( নোট: এক-ডেফিনেশনের শাসন ( [basic.def.odr] ) মোছা হয়েছে সংজ্ঞা প্রযোজ্য -। শেষ নোট ] একটি মুছে দেওয়া একটি ফাংশন সংজ্ঞা ফাংশনের প্রথম ঘোষণা বা ফাংশন টেমপ্লেটের একটি সুনির্দিষ্ট বিশেষজ্ঞতা জন্য, হইবে , সেই বিশেষজ্ঞের প্রথম ঘোষণা। [উদাহরণ:

struct sometype {
  sometype();
};
sometype::sometype() = delete;      // ill-formed; not first declaration

- শেষ উদাহরণ )

মুছে ফেলা সংজ্ঞা সহ একটি প্রাথমিক ফাংশন টেম্পলেট বিশেষ করা যেতে পারে

থাম্বের সাধারণ নিয়ম থাকা সত্ত্বেও ফাংশন টেম্পলেটগুলির বিশেষায়িতকরণ এড়াতে হয় কারণ ওভারলোড রেজোলিউশনের প্রথম ধাপে বিশেষীকরণগুলি অংশ নেয় না, এমন কিছু যুক্তি রয়েছে যেখানে এটি কার্যকর হতে পারে। যেমন ক ব্যবহারের সময় কোনও প্রকারের সাথে কোনও সংজ্ঞা ছাড়াই অ-ওভারলোডেড প্রাথমিক ফাংশন টেম্পলেট করার সময় যা কোনওরূপে অন্যথায় ম্যাচ-বাই-রূপান্তর ওভারলোডকে স্পষ্টত রূপান্তর করতে চায় না; অর্থাত্, অ-সংজ্ঞায়িত, অ-ওভারলোডেড প্রাথমিক ফাংশন টেম্পলেটটির স্পষ্টতীকরণের ক্ষেত্রে সঠিক ধরণের ম্যাচগুলি প্রয়োগ করে সুস্পষ্টভাবে সংখ্যালঘ্ন-রূপান্তর ম্যাচগুলি সরিয়ে ফেলার জন্য।

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

#include <iostream>
#include <string>

template< typename T >
void use_only_explicit_specializations(T t);

template<>
void use_only_explicit_specializations<int>(int t) {
    std::cout << "int: " << t;
}

int main()
{
    const int num = 42;
    const std::string str = "foo";
    use_only_explicit_specializations(num);  // int: 42
    //use_only_explicit_specializations(str); // undefined reference to `void use_only_explicit_specializations< ...
}

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

#include <iostream>
#include <string>

template< typename T >
void use_only_explicit_specializations(T t) = delete;

template<>
void use_only_explicit_specializations<int>(int t) {
    std::cout << "int: " << t;
}

int main()
{
    const int num = 42;
    const std::string str = "foo";
    use_only_explicit_specializations(num);  // int: 42
    use_only_explicit_specializations(str);
    /* error: call to deleted function 'use_only_explicit_specializations' 
       note: candidate function [with T = std::__1::basic_string<char>] has 
       been explicitly deleted
       void use_only_explicit_specializations(T t) = delete; */
}

আরও বেশি পঠনযোগ্য ত্রুটি বার্তা সরবরাহ করা, যেখানে মোছার উদ্দেশ্যটিও স্পষ্টভাবে দৃশ্যমান (যেখানে একটি অপরিজ্ঞাত রেফারেন্স ত্রুটি বিকাশকারীকে এটি একটি অচিন্তিত ভুল ভাবতে পারে)।

কেন আমরা কখনই এই কৌশলটি ব্যবহার করতে চাইব? আবার, স্পষ্টত বিশেষায়িতকরণ অন্তর্নিহিত রূপান্তরগুলি সুস্পষ্টভাবে মুছে ফেলার জন্য কার্যকর হতে পারে ।

#include <cstdint>
#include <iostream>

void warning_at_best(int8_t num) { 
    std::cout << "I better use -Werror and -pedantic... " << +num << "\n";
}

template< typename T >
void only_for_signed(T t) = delete;

template<>
void only_for_signed<int8_t>(int8_t t) {
    std::cout << "UB safe! 1 byte, " << +t << "\n";
}

template<>
void only_for_signed<int16_t>(int16_t t) {
    std::cout << "UB safe! 2 bytes, " << +t << "\n";
}

int main()
{
    const int8_t a = 42;
    const uint8_t b = 255U;
    const int16_t c = 255;
    const float d = 200.F;

    warning_at_best(a); // 42
    warning_at_best(b); // implementation-defined behaviour, no diagnostic required
    warning_at_best(c); // narrowing, -Wconstant-conversion warning
    warning_at_best(d); // undefined behaviour!

    only_for_signed(a);
    only_for_signed(c);

    //only_for_signed(b);  
    /* error: call to deleted function 'only_for_signed' 
       note: candidate function [with T = unsigned char] 
             has been explicitly deleted
       void only_for_signed(T t) = delete; */

    //only_for_signed(d);
    /* error: call to deleted function 'only_for_signed' 
       note: candidate function [with T = float] 
             has been explicitly deleted
       void only_for_signed(T t) = delete; */
}

0

এটি সি ++ 0 এক্স স্ট্যান্ডার্ডে নতুন জিনিস যেখানে আপনি উত্তরাধিকার সূত্রে কোনও ফাংশন মুছতে পারেন।


11
আপনি যে কোনও ফাংশন মুছতে পারেন। যেমন void foo(int); template <class T> void foo(T) = delete;সমস্ত অন্তর্নিহিত রূপান্তর বন্ধ করে দেয়। কেবল intপ্রকারের আর্গুমেন্ট গ্রহণ করা হয়, অন্যরা সমস্ত "মুছে ফেলা" ফাংশনটি ইনস্ট্যান্ট করার চেষ্টা করবে।
আঙ্কেলবেন্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.