5 এর নিয়ম - ব্যবহার করতে হবে নাকি?


20

3 এর বিধি ( নতুন সি ++ স্ট্যান্ডার্ডে 5 এর বিধি) বলেছেন:

আপনার যদি নিজেকে স্পষ্টরূপে ডেস্ট্রাক্টর, কপি নির্মাণকারী বা অনুলিপি নিয়োগের অপারেটরটি প্রকাশ করতে হয় তবে আপনার সম্ভবত তিনটিই স্পষ্টভাবে ঘোষণা করা দরকার।

তবে, অন্যদিকে, মার্টিনের " ক্লিন কোড " সমস্ত খালি নির্মাণকারী এবং ধ্বংসকারীদের অপসারণের পরামর্শ দেয় (পৃষ্ঠা 293, জি 12: বিশৃঙ্খলা ):

কোন প্রয়োগের সাথে কোনও প্রয়োগ নেই এমন কোনও ডিফল্ট নির্মাতা? এটি যা কাজ করে তা হ'ল অর্থহীন নিদর্শনগুলির সাথে কোডকে বিশৃঙ্খল করা।

তাহলে, এই দুটি বিপরীত মতামত কীভাবে পরিচালনা করবেন? খালি নির্মাণকারী / ধ্বংসকারীদের কি বাস্তবায়িত করা উচিত?


পরবর্তী উদাহরণটি ঠিক আমার অর্থ বোঝায়:

#include <iostream>
#include <memory>

struct A
{
    A( const int value ) : v( new int( value ) ) {}
    ~A(){}
    A( const A & other ) : v( new int( *other.v ) ) {}
    A& operator=( const A & other )
    {
        v.reset( new int( *other.v ) );
        return *this;
    }

    std::auto_ptr< int > v;
};
int main()
{
    const A a( 55 );
    std::cout<< "a value = " << *a.v << std::endl;
    A b(a);
    std::cout<< "b value = " << *b.v << std::endl;
    const A c(11);
    std::cout<< "c value = " << *c.v << std::endl;
    b = c;
    std::cout<< "b new value = " << *b.v << std::endl;
}

জি ++ 4.6.1 ব্যবহার করে জরিমানা সংকলন করুন:

g++ -std=c++0x -Wall -Wextra -pedantic example.cpp

এর জন্য ডেস্ট্রাক্টর struct Aখালি, সত্যই প্রয়োজন নেই। সুতরাং, এটি সেখানে থাকা উচিত, বা এটি অপসারণ করা উচিত?


15
2 টি উদ্ধৃতি বিভিন্ন জিনিস সম্পর্কে কথা বলতে। অথবা আমি আপনার বক্তব্য পুরোপুরি মিস করছি।
বেনিয়ামিন বান্নিয়ার

1
@ হংক আমার দলের কোডিং মান অনুসারে, আমাদের সর্বদা 4 টি (কনস্ট্রাক্টর, ডেস্ট্রাক্টর, অনুলিপি নির্মাণকারী) ঘোষণা করার নিয়ম রয়েছে। আমি ভাবছিলাম কি আসলেই এটি করার তাগিদ হয়? খালি থাকলেও কি আমাকে সত্যই সর্বদা ধ্বংসকারী ঘোষণা করতে হবে?
BЈовић

খালি বর্ণচর্চাকারী হিসাবে এটি সম্পর্কে চিন্তা করুন: কোড ynthesis.com/~boris/blog/2012/04/04/… । তা না হলে 3 (5) শাসন আমার নিখুঁত জ্ঞান করে তোলে, কোন ধারণা কেন এক 4. একটি নিয়ম চাইবেন
বেঞ্জামিন Bannier

@Honk নেট থেকে আপনি যে তথ্য পাবেন তার সন্ধান করুন। সব সত্য হয় না। উদাহরণস্বরূপ, virtual ~base () = default;সংকলন করবেন না (একটি ভাল কারণ সহ)
BЈовић

@ ভিজেভিচ, না আপনাকে খালি ডেস্ট্রাক্টর ঘোষণা করতে হবে না, যদি না আপনি এটিকে ভার্চুয়াল করার প্রয়োজন হয়। এবং আমরা যখন বিষয়টিতে থাকি তখন auto_ptrআপনারও ব্যবহার করা উচিত নয় ।
ডিমা

উত্তর:


44

শুরু করার জন্য নিয়মটি "সম্ভবত" বলে, তাই এটি সর্বদা প্রযোজ্য নয়।

দ্বিতীয় পয়েন্টটি আমি এখানে দেখছি যে যদি আপনাকে তিনটির মধ্যে একটির ঘোষণা করতে হয়, কারণ এটি মেমরি বরাদ্দ করার মতো বিশেষ কিছু করছে। এই ক্ষেত্রে, অন্যরা শূন্য হবে না যেহেতু তাদের একই কাজ পরিচালনা করতে হবে (যেমন অনুলিপি নির্ধারকটিতে গতিশীলভাবে বরাদ্দকৃত মেমরির বিষয়বস্তু অনুলিপি করা বা এই জাতীয় স্মৃতি মুক্ত করা)।

সুতরাং উপসংহার হিসাবে, আপনার খালি নির্মাতা বা ধ্বংসকারীদের ঘোষণা করা উচিত নয়, তবে এটি খুব সম্ভবত যে যদি কোনও প্রয়োজন হয়, অন্যদেরও প্রয়োজন হয়।

আপনার উদাহরণ হিসাবে: যেমন একটি ক্ষেত্রে, আপনি ধ্বংসকারী ছেড়ে যেতে পারেন। এটা কিছুই করে না, স্পষ্টতই। স্মার্ট পয়েন্টারগুলির ব্যবহার কোথায় এবং কেন 3 এর নিয়ম ধরে না তার একটি নিখুঁত উদাহরণ।

আপনি যদি অন্যথায় মিস করতে পারেন এমন গুরুত্বপূর্ণ কার্যকারিতা বাস্তবায়ন করতে ভুলে যেতে পারেন তবে আপনার কোডটির উপরে কোথায় দ্বিতীয় নজর রাখা উচিত এটি কেবলমাত্র একটি গাইড।


স্মার্ট পয়েন্টারগুলির সাহায্যে, ডেস্ট্রাক্টররা বেশিরভাগ ক্ষেত্রেই খালি থাকে (আমি বলব> আমার কোড বেসে 99% ডেস্ট্রাক্টর খালি রয়েছে, কারণ প্রায় প্রতিটি শ্রেণিই পিম্পল আইডিয়াম ব্যবহার করে)।
BЈовић

বাহ, এতো লাঞ্ছিত আমি এটাকে দুর্গন্ধযুক্ত বলি। অনেকগুলি কম্পাইলারের সাহায্যে পিম্পলডগুলি অনুকূলকরণ করা শক্ত হবে (উদাহরণস্বরূপ ইনলাইন করা শক্ত)।
বেঞ্জামিন ব্যানিয়ের

@ হংক "" বহু সংকলক পিম্পলড "বলতে কী বোঝ? :)
বি

@ ভিজেভিচ: দুঃখিত, টাইপো: 'পিম্পলড কোড'
বেনিয়ামিন

4

এখানে আসলে কোনও দ্বন্দ্ব নেই। 3 এর নিয়মটি ডেস্ট্রাক্টর, কপি কনস্ট্রাক্টর এবং কপি অ্যাসাইনমেন্ট অপারেটর সম্পর্কে কথা বলে। চাচা বব খালি ডিফল্ট নির্মাতাদের সম্পর্কে কথা বলেন।

আপনার যদি কোনও ডেস্ট্রাক্টর দরকার হয় তবে আপনার ক্লাসে সম্ভবত গতিশীল বরাদ্দ মেমরির পয়েন্টার রয়েছে এবং আপনি সম্ভবত একটি অনুলিপি কর্নার এবং operator=()একটি গভীর অনুলিপি করতে চান। আপনার কোনও ডিফল্ট কন্সট্রাক্টর প্রয়োজন কিনা তা সম্পূর্ণরূপে অর্থেগোনাল।

এটিও লক্ষ করুন যে সি ++ এ এমন পরিস্থিতি রয়েছে যখন আপনার খালি থাকলেও ডিফল্ট নির্মাতা প্রয়োজন। ধরা যাক আপনার ক্লাসে একটি অ-ডিফল্ট কনস্ট্রাক্টর রয়েছে। সেক্ষেত্রে সংকলকটি আপনার জন্য একটি ডিফল্ট নির্মাতা তৈরি করবে না। এর অর্থ এই যে এই শ্রেণীর বস্তুগুলি এসটিএল পাত্রে সংরক্ষণ করা যাবে না, কারণ এই ধারকরা প্রত্যাশাগুলি ডিফল্ট-নির্মাণযোগ্য হতে পারে const

অন্যদিকে, আপনি যদি কখনও নিজের শ্রেণীর অবজেক্টগুলিকে এসটিএল পাত্রে রাখার পরিকল্পনা না করেন তবে একটি খালি ডিফল্ট নির্মাতা অবশ্যই অকেজো ক্লাটার।


2

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

(আরও একটি সম্ভাব্য উদ্দেশ্য রয়েছে: ডিফল্ট ইনলাইন একের পরিবর্তে আউটলাইন সংজ্ঞা প্রদান করুন, আপনার যদি এর কোনও কারণ থাকে তবে স্পষ্ট করে ডকুমেন্ট করা ভাল)।

(*) সম্ভাব্য কারণ আমি এমন একটি বাস্তব জীবনের ঘটনা মনে নেই যেখানে তিনজনের বিধি প্রযোজ্য হয়নি, যদি আমাকে একটিতে কিছু করতে হয় তবে আমাকে অন্যগুলিতে কিছু করতে হয়েছিল।


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


উদাহরণটি আমার বক্তব্যকে প্রমাণ করে। ডেস্ট্রাক্টরটির সত্যই প্রয়োজন হয় না, তবে 3 এর নিয়ম বলে যে এটি হওয়া উচিত।
BЈовић

1

5 এর বিধি 3 এর নিয়মের একটি cautalative বর্ধন যা সম্ভাব্য বস্তুর অপব্যবহারের পুনরায় সতর্কতামূলক আচরণ behavior

আপনার যদি কোনও ডেস্ট্রাক্টর দরকার হয় তবে এর অর্থ হ'ল আপনি ডিফল্ট ব্যতীত কিছু "রিসোর্স ম্যানেজমেন্ট" করেছেন (স্রেফ মান নির্মান করুন এবং ধ্বংস করুন) )।

যেহেতু আপনি কেবল মান রাখছেন না , তাই অনুলিপি, ডিফল্ট অনুলিপি মান দ্বারা স্থানান্তর এবং স্থানান্তর , আপনি কি করতে হবে তা নির্ধারণ করতে হবে।

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

আপনি যখন অনুলিপি এবং মুভ উভয়ই সংজ্ঞায়িত করতে চান (5 এর নিয়ম) খুব বিরল: সাধারণত আপনার "বিগ মান" থাকে যা আলাদা আলাদা বস্তুগুলিকে দেওয়া হলে অনুলিপি করতে হয়, তবে অস্থায়ী বস্তু থেকে নেওয়া হলে সরানো যেতে পারে (এড়ানো) একটি ক্লোন তখন ধ্বংস )। এটি এসটিএল পাত্রে বা পাটিগণিতের পাত্রে।

একটি ক্ষেত্রে ম্যাটিক্স সমূহের হতে পারে: তারা সমর্থন কপি আছে, কারণ তারা হয় মূল্যবোধ, ( a=b; c=b; a*=2; b*=3;একে অপরের প্রভাবিত হবে) কিন্তু তারা সমর্থনকারী চলন্ত (দ্বারা অপ্টিমাইজ করা যেতে পারে a = 3*b+4*cএকটি হয়েছে +দুই temporaries নেয় এবং একটি অস্থায়ী উত্পন্ন: এড়ানো ক্লোন করতে এবং মুছে হতে পারে দরকারী)


1

আমি তিনটি নিয়মের একটি পৃথক বাক্যাংশ পছন্দ করি, যা আরও যুক্তিসঙ্গত বলে মনে হয়, যা "আপনার শ্রেণীর যদি কোনও ডেস্ট্রাক্টরের প্রয়োজন হয় (খালি ভার্চুয়াল ডেস্ট্রাক্টর ব্যতীত) সম্ভবত এটির একটি অনুলিপি নির্মাণকারী এবং অ্যাসাইনমেন্ট অপারেটরও প্রয়োজন।"

এটি ডেস্ট্রাক্টরের কাছ থেকে ওয়ান ওয়ে সম্পর্ক হিসাবে নির্দিষ্ট করা কয়েকটি বিষয়কে আরও পরিষ্কার করে তোলে:

  1. আপনি কেবলমাত্র একটি অপ্টিমাইজেশন হিসাবে একটি অ-ডিফল্ট অনুলিপি নির্মাণকারী বা অ্যাসাইনমেন্ট অপারেটর সরবরাহ করেন এমন ক্ষেত্রে এটি প্রয়োগ হয় না It

  2. নিয়মের কারণ হ'ল ডিফল্ট কপিরাইট কনস্ট্রাক্টর বা অ্যাসাইনমেন্ট অপারেটর ম্যানুয়াল রিসোর্স ম্যানেজমেন্ট স্ক্রু করতে পারে। আপনি যদি ম্যানুয়ালি রিসোর্স পরিচালনা করছেন তবে আপনি সম্ভবত বুঝতে পেরেছেন যে এগুলি ছেড়ে দেওয়ার জন্য আপনার কোনও ডেস্ট্রাক্টর দরকার।


-3

আলোচনায় এখনও উল্লেখ করা হয়নি এমন আরও একটি বিষয় রয়েছে: একজন ধ্বংসকারীকে সর্বদা ভার্চুয়াল হওয়া উচিত।

struct A
{
    A( const int value ) : v( new int( value ) ) {}
    virtual ~A(){}
    ...
}

সমস্ত উত্পন্ন ক্লাসেও ভার্চুয়াল তৈরি করতে কনস্ট্রাক্টরটিকে বেস শ্রেণিতে ভার্চুয়াল হিসাবে ঘোষণা করা দরকার। সুতরাং, এমনকি যদি আপনার বেস শ্রেণিটির জন্য ডেস্ট্রাক্টরের প্রয়োজন না হয় তবে আপনি খালি ডেস্ট্রাক্টর ঘোষণা এবং প্রয়োগ করেন।

আপনি যদি (-Wall -Wextra -Weffc ++) g ++ এ সমস্ত সতর্কতা রেখে দেন তবে আপনাকে এই সম্পর্কে সতর্ক করবে। আমি যে কোনও ক্লাসে সর্বদা ভার্চুয়াল ডেস্ট্রাক্টর ঘোষণা করা ভাল অভ্যাস হিসাবে বিবেচনা করি, কারণ আপনি কখনই জানেন না, যদি আপনার শ্রেণি অবশেষে একটি বেস শ্রেণিতে পরিণত হয়। যদি ভার্চুয়াল ডেস্ট্রাক্টরের প্রয়োজন না হয় তবে এটি কোনও ক্ষতি করে না। যদি তা হয় তবে ত্রুটিটি খুঁজে পেতে আপনার সময় সাশ্রয় হয়।


1
তবে আমি ভার্চুয়াল কনস্ট্রাক্টর চাই না। আমি যদি এটি করি তবে যে কোনও পদ্ধতিতে প্রতিটি কল ভার্চুয়াল প্রেরণ ব্যবহার করবে। বিটিডাব্লু একটি নোট নিন যে সি ++ এ "ভার্চুয়াল কনস্ট্রাক্টর" বলে কোনও জিনিস নেই। এছাড়াও, আমি উদাহরণটি খুব উচ্চ সতর্কতার স্তর হিসাবে সংকলন করেছি।
BЈовић

আইআইআরসি, জিসিসি তার সতর্কতার জন্য যে নিয়মটি ব্যবহার করে এবং আমি যেভাবে নিয়ম অনুসরণ করি সেই নিয়মটি হ'ল ক্লাসে অন্য কোনও ভার্চুয়াল পদ্ধতি থাকলে ভার্চুয়াল ডেস্ট্রাক্টর থাকা উচিত।
জুলাই
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.