সি ++ - স্ট্যান্ডার্ড :: শেয়ারড_পিটার বা বুস্ট :: শেয়ারড_পিটিআরের রেফারেন্সগুলি পাস করা


115

আমার যদি এমন একটি ফাংশন থাকে যা এর সাথে কাজ করা প্রয়োজন shared_ptr, তবে এটির কোনও রেফারেন্সটি পাঠানো কি আরও দক্ষ হবে না (যাতে shared_ptrঅবজেক্টটি অনুলিপি করা এড়ানোর জন্য )? সম্ভাব্য খারাপ পার্শ্ব প্রতিক্রিয়াগুলি কী কী? আমি দুটি সম্ভাব্য কেস কল্পনা করি:

1) ফাংশনের ভিতরে একটি অনুলিপি যুক্তির মতো তৈরি করা হয়

ClassA::take_copy_of_sp(boost::shared_ptr<foo> &sp)  
{  
     ...  
     m_sp_member=sp; //This will copy the object, incrementing refcount  
     ...  
}  

2) ফাংশনটির ভিতরে যুক্তিটি কেবল ব্যবহৃত হয়, যেমন

Class::only_work_with_sp(boost::shared_ptr<foo> &sp) //Again, no copy here  
{    
    ...  
    sp->do_something();  
    ...  
}  

আমি উভয় ক্ষেত্রেই boost::shared_ptr<foo>রেফারেন্সের পরিবর্তে মান দ্বারা পাস করার একটি ভাল কারণ দেখতে পাচ্ছি না । মান দ্বারা পাস করা কেবল অনুলিপিটির কারণে রেফারেন্স গণনাটিকে "সাময়িকভাবে" বৃদ্ধি করবে এবং তারপরে ফাংশনের সুযোগ থেকে বেরিয়ে যাওয়ার সময় এটি হ্রাস পাবে। আমি কি কিছু উপেক্ষা করছি?

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


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

উত্তর:


113

একটি স্বতন্ত্র shared_ptrউদাহরণের বিন্দুটি গ্যারান্টি দেওয়া (যতদূর সম্ভব) যে যতক্ষণ shared_ptrএটি সুযোগে থাকবে, এটি যে বস্তুটিকে নির্দেশ করে তা এখনও বিদ্যমান থাকবে, কারণ এর রেফারেন্স গণনা কমপক্ষে 1 হবে।

Class::only_work_with_sp(boost::shared_ptr<foo> sp)
{
    // sp points to an object that cannot be destroyed during this function
}

সুতরাং একটি রেফারেন্স ব্যবহার করে shared_ptr, আপনি যে গ্যারান্টি অক্ষম। সুতরাং আপনার দ্বিতীয় ক্ষেত্রে:

Class::only_work_with_sp(boost::shared_ptr<foo> &sp) //Again, no copy here  
{    
    ...  
    sp->do_something();  
    ...  
}

আপনি কীভাবে জানবেন যে sp->do_something()নাল পয়েন্টারটির কারণে উড়ে যাবে না?

কোডের '' ... 'বিভাগগুলিতে কী আছে তা নির্ভর করে। আপনি যদি প্রথম '...' চলাকালীন কোনও কিছু কল করেন তবে তার shared_ptrএকই অজানাটিকে সাফ করার পার্শ্ব-প্রতিক্রিয়া (কোডের অন্য কোনও অংশে) রয়েছে ? এবং যদি এটি হয়ে ওঠে তবে কেবলমাত্র shared_ptrসেই অবজেক্টটির সাথে কেবল আলাদা করা যায়? বাই বাই অবজেক্ট, আপনি যেখানে চেষ্টা করতে এবং এটি ব্যবহার করতে চলেছেন ঠিক সেখানে।

সুতরাং এই প্রশ্নের উত্তর দেওয়ার দুটি উপায় রয়েছে:

  1. আপনার পুরো প্রোগ্রামের উত্সটি খুব সাবধানে পরীক্ষা করুন যতক্ষণ না আপনি নিশ্চিত হন যে ফাংশন বডি চলাকালীন অবজেক্টটি মারা যাবে না।

  2. পরামিতিটিকে পরিবর্তনের পরিবর্তে একটি রেফারেন্সের পরিবর্তে আলাদা স্বতন্ত্র বস্তুতে পরিণত করুন।

এখানে প্রযোজ্য সাধারণ বিট: কার্য সম্পাদনের জন্য আপনার কোডে ঝুঁকিপূর্ণ পরিবর্তনগুলি ঘটাবেন না যতক্ষণ না আপনি কোনও প্রোফাইকারের কাছে আপনার পণ্যকে বাস্তবসম্মত পরিস্থিতিতে সময় হিসাবে নির্ধারণ করেন এবং সিদ্ধান্ত হিসাবে পরিমাপ করেন যে আপনি যে পরিবর্তনটি করতে চান তা পরিবর্তন করে দেবে পারফরম্যান্সে উল্লেখযোগ্য পার্থক্য।

মন্তব্যকারী জিকিউ জন্য আপডেট

এখানে একটি স্বতন্ত্র উদাহরণ। এটি ইচ্ছাকৃতভাবে সহজ, তাই ভুলটি সুস্পষ্ট হবে। প্রকৃত উদাহরণগুলিতে, ভুলটি এতটা সুস্পষ্ট নয় কারণ এটি আসল বিবরণের স্তরগুলিতে লুকানো রয়েছে।

আমাদের একটি ফাংশন রয়েছে যা কোথাও একটি বার্তা প্রেরণ করবে। এটি একটি বৃহত্তর বার্তা হতে পারে তার পরিবর্তে std::stringএটি সম্ভবত একাধিক স্থানে পাস হওয়ার সাথে সাথে অনুলিপি করা হয় না, আমরা shared_ptrএকটি স্ট্রিং এ ব্যবহার করি :

void send_message(std::shared_ptr<std::string> msg)
{
    std::cout << (*msg.get()) << std::endl;
}

(আমরা উদাহরণস্বরূপ এটি কনসোলে কেবল "প্রেরণ" করব)।

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

std::shared_ptr<std::string> previous_message;

তারপরে আমরা আমাদের নির্দিষ্ট করা বিধি অনুযায়ী আমাদের ফাংশনটি সংশোধন করি:

void send_message(std::shared_ptr<std::string> msg)
{
    previous_message = 0;
    std::cout << *msg << std::endl;
    previous_message = msg;
}

সুতরাং, আমরা প্রেরণ শুরু করার আগে আমরা বর্তমানের পূর্ববর্তী বার্তাটি বাতিল করি এবং তারপরে পাঠানো শেষ হওয়ার পরে আমরা নতুন পূর্ববর্তী বার্তাটি সংরক্ষণ করতে পারি। সব ভালো. এখানে কিছু পরীক্ষার কোড দেওয়া হল:

send_message(std::shared_ptr<std::string>(new std::string("Hi")));
send_message(previous_message);

এবং যেমন প্রত্যাশা করা হয়েছে, এই Hi!দু'বার মুদ্রণ ।

এখন মিঃ মেনটেনিয়ার আসেন, যিনি কোডটি দেখেন এবং ভাবেন: আরে, সেই পরামিতিটি send_messageহ'ল shared_ptr:

void send_message(std::shared_ptr<std::string> msg)

স্পষ্টতই এটিকে পরিবর্তন করা যেতে পারে:

void send_message(const std::shared_ptr<std::string> &msg)

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

তবে আসল সমস্যাটি হ'ল এখন পরীক্ষার কোডটি অপরিবর্তিত আচরণের প্রদর্শন করবে (ভিজ্যুয়াল সি ++ 2010-এ ডিবাগ তৈরি করে, এটি ক্র্যাশ হয়ে যায়)।

মিঃ মেইনটেনার এতে অবাক, তবে send_messageসমস্যাটি ঘটতে থামাতে প্রয়াসে একটি প্রতিরক্ষামূলক চেক যোগ করেছেন :

void send_message(const std::shared_ptr<std::string> &msg)
{
    if (msg == 0)
        return;

তবে অবশ্যই এটি এখনও এগিয়ে যায় এবং ক্র্যাশ হয়, কারণ msgযখন send_messageডাকা হয় তখন কখনই শূন্য হয় না ।

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

সহজ সমাধান, যেখানে আপনি কোনও ক্রিয়াকলাপটি shared_ptrঅ-শূন্য জুড়ে চলার উপর নির্ভর করতে সক্ষম হতে চান তা হ'ল shared_ptrকার্যটির কোনও বিদ্যমানতার রেফারেন্সের উপর নির্ভর না করে তার নিজের সত্য বরাদ্দ করা shared_ptr

নেতিবাচক দিকটি হ'ল অনুলিপি করা shared_ptrযায় না: এমনকি "লক-ফ্রি" বাস্তবায়নগুলি থ্রেডিং গ্যারান্টি সম্মানের জন্য একটি ইন্টারলকড অপারেশন ব্যবহার করতে হয়। সুতরাং পরিস্থিতিতে যেখানে একটি প্রোগ্রাম উল্লেখযোগ্যভাবে পরিবর্তন গতি আনে যাবে হতে পারে shared_ptrএকটি মধ্যে shared_ptr &। তবে এটি কোনও পরিবর্তন নয় যা নিরাপদে সমস্ত প্রোগ্রামে করা যায়। এটি প্রোগ্রামটির যৌক্তিক অর্থকে পরিবর্তন করে।

মনে রাখবেন যে আমরা যদি এর std::stringপরিবর্তে std::shared_ptr<std::string>এবং এর পরিবর্তে ব্যবহার করি তবে অনুরূপ বাগটি ঘটবে :

previous_message = 0;

বার্তা পরিষ্কার করতে, আমরা বলেছিলাম:

previous_message.clear();

তারপরে লক্ষণটি হ'ল দুর্ঘটনাক্রমে খালি বার্তা প্রেরণ করা হবে, পরিবর্তিত আচরণের পরিবর্তে। একটি খুব বড় স্ট্রিংয়ের অতিরিক্ত অনুলির ব্যয় কপি করার ব্যয়ের চেয়ে অনেক বেশি তাৎপর্যপূর্ণ হতে পারে shared_ptr, সুতরাং বাণিজ্য বন্ধ আলাদা হতে পারে।


16
ভাগ করা_প্টার যা ইতিমধ্যে পাস করা হয়েছে তা কল সাইটে একটি স্কোপে বাস করে। আপনি সম্ভবত একটি বিস্তৃত পরিস্থিতি তৈরি করতে সক্ষম হবেন যেখানে এই প্রশ্নের কোডটি একটি ঝুঁকির পয়েন্টারের কারণে ফুঁসে উঠবে তবে আমি মনে করি রেফারেন্স প্যারামিটারের চেয়ে আপনার আরও বড় সমস্যা আছে!
ম্যাগনাস হফ

10
এটি কোনও সদস্যের মধ্যে সংরক্ষণ করা যেতে পারে। আপনি সেই সদস্যটিকে সাফ করার জন্য এমন কিছু কল করতে পারেন। স্মার্ট_পিটারের পুরো বিষয়টি হ'ল হায়ারারচি বা স্কোপগুলিতে কল স্ট্যাকের চারপাশে বাসা বাঁধার এড়াতে পারা যায়, সুতরাং সেই কারণেই লাইফটাইম এই জাতীয় প্রোগ্রামগুলিতে তা করে না বলে মনে করা ভাল।
ড্যানিয়েল আর্উইকার

7
যদিও এটি আসলে আমার দৃষ্টিভঙ্গি নয়! আপনি যদি ভাবেন যে আমি যা বলছি তা আমার কোডের সাথে সুনির্দিষ্ট কিছু হয় তবে আপনি আমাকে বুঝতে পারেন নি। আমি শেয়ারড_পিটারের প্রথম স্থানে থাকার কারণে একটি অনিবার্যভাবে জড়িত থাকার কথা বলছি: অনেকগুলি অবজেক্টের লাইফটাইম কেবল ফাংশন কলগুলির সাথে সম্পর্কিত নয়।
ড্যানিয়েল আর্উইকার

8
@ ড্যানিয়েলআরউইকার আপনার সমস্ত পয়েন্টের সাথে সম্পূর্ণ একমত এবং বিরোধিতার মাত্রা দেখে অবাক হয়েছেন। আপনার উদ্বেগকে আরও প্রাসঙ্গিক করে তোলে এমন কিছু হ'ল থ্রেডিং, যখন এটি জড়িত হয় যখন কোনও বস্তুর বৈধতা সম্পর্কে গ্যারান্টি অনেক বেশি গুরুত্বপূর্ণ হয়ে ওঠে। ভাল উত্তর.
রেডম্যান

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

115

আমি নিজেকে সর্বোচ্চ ভোটের উত্তরের সাথে একমত হতে দেখলাম, তাই আমি বিশেষজ্ঞের মতামত খুঁজতে গিয়েছিলাম এবং তারা এখানে। Http://channel9.msdn.com/Shows/Going+Dip/C-and-Beyond-2011- থেকে স্কট-আান্ড্রেই- এবং- হার্ব- অ্যাস্ক -উস- কিছু না

ভেষজ সুটার: "আপনি যখন শেয়ার্ড_পটারগুলি পাস করেন, অনুলিপিগুলি ব্যয়বহুল"

স্কট মায়ারস: "আপনি ভাগ করে নেওয়া_পিত্তর সম্পর্কে বিশেষ কিছু নেই যখন আপনি এটি মান দিয়ে পাস করেন বা রেফারেন্স দিয়ে এটি পাস করেন কিনা। অন্য যে কোনও ব্যবহারকারীর সংজ্ঞায়িত ধরণের জন্য আপনি ব্যবহার করেন ঠিক একই বিশ্লেষণটি ব্যবহার করুন People লোকেদের মনে হয় যে শেয়ারড_পিটার কোনওভাবে সমাধান করে পরিচালনার সমস্ত সমস্যা, এবং এটি যেহেতু এটি ছোট, এটি অগত্যা মূল্য দিয়ে পাস করা সস্তা। এটি অনুলিপি করতে হয়, এবং এর সাথে একটি ব্যয় যুক্ত হয় ... এটি মান দিয়ে পাস করা ব্যয়বহুল, তাই যদি আমি এড়াতে পারি তবে এটি আমার প্রোগ্রামে যথাযথ শব্দার্থবিজ্ঞান সহ, আমি কনস্ট বা রেফারেন্সের পরিবর্তে এটি পাস করব "

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

আপডেট: ভেষজ এখানে এটির প্রসারিত হয়েছে: http://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-paraters/ , যদিও গল্পের নৈতিকতাটি হচ্ছে আপনার পাস করা উচিত নয় শেয়ারড_পটার্স একেবারে "যদি না আপনি নিজেরাই স্মার্ট পয়েন্টার ব্যবহার করতে বা পরিচালনা করতে চান, যেমন মালিকানা ভাগ করতে বা হস্তান্তর করতে।"


8
ভাল লাগছে! বিষয়টির শীর্ষস্থানীয় দু'জন বিশেষজ্ঞকে প্রকাশ্যে এসও-র প্রচলিত জ্ঞানকে খণ্ডন করতে দেখলাম great
স্টিফান টলকসডর্ফ

3
"আপনি ভাগ করে এটিকে মূল্য দিয়ে যান, বা রেফারেন্স দিয়ে এটি পাস করেন কিনা এ বিষয়ে যখন ভাগ করা_পিটারের বিশেষ কিছু নেই" - আমি সত্যই এর সাথে একমত নই। এটি বিশেষ। ব্যক্তিগতভাবে আমি বরং এটি নিরাপদে খেলব এবং সামান্য পারফরম্যান্সের হিট নেব। কোডের কোনও নির্দিষ্ট ক্ষেত্র যদি আমার অপ্টিমাইজ করা প্রয়োজন তবে অবশ্যই, আমি কনস্টের রেফ দ্বারা শেয়ারড_পিট্র পাসের পারফরম্যান্স সুবিধাগুলি সন্ধান করব।
জেসনজেড

3
এটি লক্ষণীয় বিষয়ও আকর্ষণীয় যে, যখন ওজনের অতিরিক্ত ব্যবহারের বিষয়ে shared_ptrচুক্তি হয়েছিল, তখন পাস-বাই-ভ্যালু-বনাম-রেফারেন্স ইস্যু সম্পর্কে কোনও চুক্তি হয়নি।
নিকল বোলাস

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

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

22

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

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

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


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

18

হ্যাঁ, একটি রেফারেন্স নেওয়া ঠিক আছে। আপনি পদ্ধতিটি ভাগ করে নেওয়া মালিকানা দিতে চান না; এটি কেবল এটির সাথে কাজ করতে চায়। আপনি প্রথম মামলার জন্যও একটি রেফারেন্স নিতে পারেন, যেহেতু আপনি যেভাবে এটি অনুলিপি করেন। তবে প্রথম ক্ষেত্রে এটি মালিকানা নেয় । এখনও একবারে এটি অনুলিপি করার জন্য এই কৌশলটি রয়েছে:

void ClassA::take_copy_of_sp(boost::shared_ptr<foo> sp) {
    m_sp_member.swap(sp);
}

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


সম্পাদনা : অবশ্যই, অন্যরা দেখায়, এটি কেবলমাত্র সত্য যদি আপনি নিজের কোডটি জানেন এবং জানেন যে আপনি কোনওভাবে পাস করা ভাগ করা পয়েন্টারটিকে পুনরায় সেট করেন না। যদি সন্দেহ হয়, কেবল মান দ্বারা পাস করুন।


11

এটা তোলে পাস বুদ্ধিমানের shared_ptrদ্বারা গুলি const&। এটি সম্ভবত সমস্যার সৃষ্টি করবে না ( shared_ptrএর্উইকারের বিবরণ অনুসারে ফাংশন কল চলাকালীন রেফারেন্সটি মুছে ফেলা হয়েছে এমন সম্ভাব্য ক্ষেত্রে ব্যতীত ) এবং আপনি যদি এগুলির অনেক কিছু পাস করেন তবে সম্ভবত এটি দ্রুততর হবে। মনে করে দেখ; ডিফল্ট boost::shared_ptrথ্রেড নিরাপদ, সুতরাং এটি অনুলিপি করা একটি থ্রেড নিরাপদ বৃদ্ধি অন্তর্ভুক্ত।

ন্যায়বিচারের const&পরিবর্তে ব্যবহারের চেষ্টা করুন &কারণ অস্থায়ী বস্তুগুলি অ-নিরপেক্ষ রেফারেন্স দ্বারা পাস করা হতে পারে না। (যদিও এমএসভিসিতে একটি ভাষা বর্ধন আপনাকে যেকোন উপায়ে এটি করার অনুমতি দেয়)


3
হ্যাঁ, আমি সবসময় কনস্ট্যান্ড রেফারেন্স ব্যবহার করি, আমি এটি কেবল আমার উদাহরণে রাখতে ভুলে গেছি। যাইহোক, এমএসভিসি অস্থায়ী রেফারেন্সগুলিকে কোনও বাগের জন্য নয় বরং অস্থায়ী রেফারেন্সগুলিকে আবদ্ধ করতে দেয়, কারণ ডিফল্টরূপে এটিতে "সি / সি ++ -> ভাষা -> ভাষা এক্সটেনশন অক্ষম করুন" "NO" তে সেট করা থাকে। এটি সক্ষম করুন এবং এটি তাদের সংকলন করবে না ...
অবীগগলি

আবিগলি: সিরিয়াসলি? খুব সুন্দর! আমি এটিকে কাজে লাগিয়ে দেব, আগামীকাল প্রথম জিনিসটি;)
ম্যাগনাস হফ

10

দ্বিতীয় ক্ষেত্রে, এটি করা সহজ:

Class::only_work_with_sp(foo &sp)
{    
    ...  
    sp.do_something();  
    ...  
}

আপনি এটি হিসাবে কল করতে পারেন

only_work_with_sp(*sp);

3
আপনি যখন পয়েন্টারের একটি অনুলিপি নেওয়ার দরকার নেই তখন আপনি যদি অবজেক্ট রেফারেন্সগুলি ব্যবহার করার জন্য কনভেনশনটি অবলম্বন করেন তবে এটি আপনার উদ্দেশ্যটিও নথিভুক্ত করে। এটি আপনাকে কনস্ট কনফারেন্স ব্যবহারের সুযোগ দেয়।
মার্ক রান্সম

হ্যাঁ, আমি অভিব্যক্তিগুলির জন্য রেফারেন্সগুলির ব্যবহার হিসাবে প্রকাশের উপায় হিসাবে সম্মত হই যে ডাকা ফাংশনটি সেই অবজেক্ট সম্পর্কে কোনও কিছুই "মনে রাখছে না"। সাধারণত আমি পয়েন্টার আনুষ্ঠানিক যুক্তি ব্যবহার করি যদি ফাংশনটি অবজেক্টটির "ট্র্যাক রাখা" হয়
অ্যাবিগগলি

3

ফাংশন স্পষ্টভাবে পয়েন্টারটি সংশোধন করতে না পারলে আমি একটি "সরল" রেফারেন্স এড়িয়ে যাব।

একজন const & উদাহরণ আরও অপ্টিমাইজেশন সক্ষম করতে মতো কিছু শর্তের দূরে ইনলাইনিং মত - যখন ছোট ফাংশন কলিং কোন যুক্তিসম্মত মাইক্রো-অপ্টিমাইজেশান করা যেতে পারে। এছাড়াও, বৃদ্ধি / হ্রাস - যেহেতু এটি থ্রেড নিরাপদ - এটি একটি সিঙ্ক্রোনাইজেশন পয়েন্ট। যদিও আমি বেশিরভাগ পরিস্থিতিতে এটির চেয়ে বড় পার্থক্যের আশা করব না।

সাধারণত, আপনার যদি না করার কারণ না থাকে তবে আপনার সহজ স্টাইলটি ব্যবহার করা উচিত। তারপরে, হয় const &ধারাবাহিকভাবে ব্যবহার করুন , বা আপনি কেবল কয়েকটি জায়গায় ব্যবহার করলে কেন একটি মন্তব্য যুক্ত করুন।


3

আমি কনস্ট্যান্ট রেফারেন্স দ্বারা ভাগ করা পয়েন্টারটি পাস করার পক্ষে পরামর্শ দেব - একটি শব্দার্থক যা পয়েন্টারের সাথে ফাংশনটি পাস হচ্ছে সেই পয়েন্টারের মালিক নয়, যা বিকাশকারীদের জন্য একটি পরিষ্কার আইডিয়া।

একমাত্র সমস্যাটি হ'ল একাধিক থ্রেড প্রোগ্রামগুলিতে যা ভাগ করা পয়েন্টার দ্বারা নির্দেশিত বস্তুটি অন্য থ্রেডে নষ্ট হয়ে যায়। সুতরাং এটি বলা নিরাপদ যে ভাগ করা পয়েন্টারের কনস্টের রেফারেন্স ব্যবহার করে একক থ্রেডেড প্রোগ্রামে নিরাপদ।

নন-কনস্ট্যান্ট রেফারেন্স দ্বারা ভাগ করা পয়েন্টারটি পাস করা কখনও কখনও বিপজ্জনক হয় - কারণটি হ'ল অদলবদল এবং পুনরায় সেট করা ফাংশনটি ভিতরে ফাংশনটি ডেকে আনতে পারে যাতে ফাংশন ফিরে আসার পরেও বৈধ হিসাবে বিবেচিত অবজেক্টটি ধ্বংস করতে পারে।

এটি অকাল অপটিমাইজেশন সম্পর্কে নয়, আমার ধারণা - এটি সিপিইউ চক্রের অপ্রয়োজনীয় বর্জ্য এড়ানো সম্পর্কে যখন আপনি কী করতে চান তা পরিষ্কার হয়ে যায় এবং কোডিং আইডিয়ামটি দৃ fellow়ভাবে আপনার সহকর্মী বিকাশকারীদের দ্বারা গ্রহণ করা হয়েছিল।

শুধু আমার 2 সেন্ট :-)


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

3

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

উদাহরণে ফিরে যেতে:

Class::only_work_with_sp( foo &sp ) //Again, no copy here  
{    
    ...  
    sp.do_something();  
    ...  
}

আপনি কীভাবে জানবেন যে sp.do_something()ঝোলাবাঁকা পয়েন্টারের কারণে উড়ে যাবে না?

সত্যটি হ'ল শেয়ারড_পিটার বা না, কনস্ট বা না, এটি যদি ঘটতে পারে তবে spথ্রেডের মধ্যে প্রত্যক্ষ বা অপ্রত্যক্ষভাবে মালিকানা ভাগ করে নেওয়ার মতো কোনও বিষয় মিস করবেন delete this, আপনার একটি বিজ্ঞপ্তি মালিকানা বা অন্য মালিকানা ত্রুটি রয়েছে।


2

একটি জিনিস যা আমি এখনও উল্লেখ করি নি তা হ'ল আপনি যখন রেফারেন্সের সাথে ভাগ করে নেওয়া পয়েন্টারগুলি পাস করেন, আপনি যদি বেস ক্লাসের শেয়ারড পয়েন্টারকে রেফারেন্সের মাধ্যমে একটি উত্পন্ন শ্রেণি ভাগ করে নেওয়া পয়েন্টারটি পাস করতে চান তবে আপনি যে ইমপ্লাইভ রূপান্তরটি হারাবেন তা হারাবেন।

উদাহরণস্বরূপ, এই কোডটি একটি ত্রুটি তৈরি করবে, তবে আপনি যদি test()এমন পরিবর্তন করেন যাতে ভাগ করা পয়েন্টারটি রেফারেন্স দ্বারা পাস না হয় তবে এটি কার্যকর হবে ।

#include <boost/shared_ptr.hpp>

class Base { };
class Derived: public Base { };

// ONLY instances of Base can be passed by reference.  If you have a shared_ptr
// to a derived type, you have to cast it manually.  If you remove the reference
// and pass the shared_ptr by value, then the cast is implicit so you don't have
// to worry about it.
void test(boost::shared_ptr<Base>& b)
{
    return;
}

int main(void)
{
    boost::shared_ptr<Derived> d(new Derived);
    test(d);

    // If you want the above call to work with references, you will have to manually cast
    // pointers like this, EVERY time you call the function.  Since you are creating a new
    // shared pointer, you lose the benefit of passing by reference.
    boost::shared_ptr<Base> b = boost::dynamic_pointer_cast<Base>(d);
    test(b);

    return 0;
}

1

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

রেফারেন্স দ্বারা পাস ঠিক আছে

কনস্টের রেফারেন্স দিয়ে পাস করা ভাল, এবং সাধারণত এটি ব্যবহার করা যেতে পারে, কারণ এটি নির্দেশিত বস্তুর উপর কনস্ট-নেস চাপায় না।

আপনি না কারণে একটি রেফারেন্স ব্যবহার করে পয়েন্টার হারানোর ঝুঁকিতে। এই রেফারেন্সটি প্রমাণ দেয় যে আপনার কাছে স্ট্যাকের আগে স্মার্ট পয়েন্টারটির একটি অনুলিপি ছিল এবং কেবলমাত্র একটি থ্রেডই কল স্ট্যাকের মালিক, যাতে প্রাক-বিদ্যমান অনুলিপিটি চলে না।

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

আপনার স্মার্ট পয়েন্টারটিকে সর্বদা রেফারেন্স হিসাবে সংরক্ষণ করা উচিত নয় । আপনার Class::take_copy_of_sp(&sp)উদাহরণটি এর জন্য সঠিক ব্যবহার দেখায়।


1
"রেফারেন্স ব্যবহারের কারণে আপনার পয়েন্টারটি হারাতে ঝুঁকি নেই That এই রেফারেন্সটি প্রমাণ করে যে আপনার স্ট্যাকের আগে স্মার্ট পয়েন্টারটির একটি অনুলিপি ছিল" বা কোনও ডেটা সদস্য ...?
ড্যানিয়েল আর্উইকার

বুস্ট :: থ্রেড এবং বুস্টের জাদুটি বিবেচনা করুন: রেফ: বুস্ট :: ফাংশন <int> ফাংশনপয়েন্টার = বুস্ট :: বাইন্ড (doSomeoming, boost :: ref (sharedPtrInstance)); m_workerThread = নতুন বুস্ট :: থ্রেড (ফাংশনপয়েন্টার); ... শেয়ারডপিটিআরআইন্সট্যান্স মুছুন
জেসন হ্যারিসন

1

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

void FooTakesReference( boost::shared_ptr< int > & ptr )
{
    ptr.reset(); // We reset, and so does sharedA, memory is deleted.
}

void FooTakesValue( boost::shared_ptr< int > ptr )
{
    ptr.reset(); // Our temporary is reset, however sharedB hasn't.
}

void main()
{
    boost::shared_ptr< int > sharedA( new int( 13 ) );
    boost::shared_ptr< int > sharedB( new int( 14 ) );

    FooTakesReference( sharedA );

    FooTakesValue( sharedB );
}

উদাহরণটি আমরা দেখতে যে ক্ষণস্থায়ী থেকে sharedA রেফারেন্স দ্বারা পারবেন FooTakesReference মূল পয়েন্টার, যা 0 থেকে এটি ব্যবহার গণনা হ্রাস, এটা ডেটা অন্তক রিসেট করতে। FooTakesValue তবে মূল পয়েন্টারটি পুনরায় সেট করতে পারে না, ভাগ করে নেওয়াB এর ডেটা গ্যারান্টি দেওয়া এখনও ব্যবহারযোগ্য us যখন অন্য বিকাশকারী অনিবার্যভাবে পাশাপাশি উপস্থিত হয় এবং ভাগ করে নেওয়া'র ভঙ্গুর অস্তিত্বের উপর পিগব্যাক করার চেষ্টা করে তখন বিশৃঙ্খলা দেখা দেয়। ভাগ্যবান শেয়ার্ডবি বিকাশকারী, তবে, তার পৃথিবীতে সমস্ত ঠিক আছে বলে তাড়াতাড়ি বাড়ি চলে যায়।

কোড সুরক্ষা, এই ক্ষেত্রে, কোনও গতি উন্নতি অনুলিপি তৈরির তুলনায় অনেক বেশি we একই সাথে, বুস্ট :: শেয়ারড_পিটার মানে কোড সুরক্ষা উন্নত করা। কোনও কিছুর জন্য যদি এই জাতীয় কুলুঙ্গি অপ্টিমাইজেশানের প্রয়োজন হয় তবে একটি অনুলিপি থেকে রেফারেন্সে যাওয়া আরও সহজ হবে।


1

স্যান্ডি লিখেছেন: "দেখে মনে হচ্ছে যে এখানে সমস্ত উপকারিতা এবং বিস্ময়করতা কেবল শেয়ারড_পিটার নয়, রেফারেন্স দিয়ে পাস করা যে কোনও প্রকারের পক্ষে সাধারণীকরণ করা যেতে পারে" "

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

আমি আগের বাক্যটিতে "প্রায়" লিখেছিলাম কারণ পারফরম্যান্স উদ্বেগের কারণ হতে পারে এবং বিরল ক্ষেত্রে এটি 'ন্যায্য' হতে পারে তবে আমি নিজেও এই দৃশ্যটি এড়িয়ে যাব এবং নিজেই অন্যান্য অপ্টিমাইজেশন সমাধানগুলি নিজেরাই সন্ধান করব যেমন গম্ভীরভাবে দেখার জন্য ইন্ডিরিয়ারেশন, অলস মূল্যায়ন ইত্যাদির আরও একটি স্তর যুক্ত করার সময় ..

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


1

আমি এমন একটি প্রকল্পে কাজ করতাম যে নীতিটি মূল্য দ্বারা স্মার্ট পয়েন্টারগুলি পাস করার বিষয়ে খুব দৃ strong় ছিল। যখন আমাকে কিছু পারফরম্যান্স বিশ্লেষণ করতে বলা হয়েছিল - আমি দেখেছি যে স্মার্ট পয়েন্টারগুলির রেফারেন্স কাউন্টারগুলির বৃদ্ধি এবং হ্রাসের জন্য অ্যাপ্লিকেশনটি ব্যবহৃত প্রসেসরের সময়ের 4-6% এর মধ্যে ব্যয় করে।

ড্যানিয়েল আর্উইকারের বর্ণনা অনুযায়ী অদ্ভুত ক্ষেত্রে সমস্যা না এড়াতে আপনি যদি স্মার্ট পয়েন্টারগুলি মান দিয়ে পাস করতে চান তবে নিশ্চিত হয়ে নিন যে আপনি এর মূল্য প্রদান করছেন কিনা তা আপনি নিশ্চিত করেছেন।

যদি আপনি কোনও রেফারেন্সের সাথে যাওয়ার সিদ্ধান্ত নেন তবে কনফারেন্স রেফারেন্সটি ব্যবহারের মূল কারণ হ'ল যখন ইন্টারফেসে আপনি যে ক্লাসটি ব্যবহার করেন সেই শ্রেণীর উত্তরাধিকারসূত্রে ক্লাস থেকে ভাগ করে নেওয়া পয়েন্টারটি পাস করার দরকার হয় তখন অন্তর্নিহিত আপকাস্টিং করা সম্ভব হয়।


0

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


0
struct A {
  shared_ptr<Message> msg;
  shared_ptr<Message> * ptr_msg;
}
  1. মান দ্বারা পাস:

    void set(shared_ptr<Message> msg) {
      this->msg = msg; /// create a new shared_ptr, reference count will be added;
    } /// out of method, new created shared_ptr will be deleted, of course, reference count also be reduced;
  2. রেফারেন্স দ্বারা পাস:

    void set(shared_ptr<Message>& msg) {
     this->msg = msg; /// reference count will be added, because reference is just an alias.
     }
  3. পয়েন্টার দ্বারা পাস:

    void set(shared_ptr<Message>* msg) {
      this->ptr_msg = msg; /// reference count will not be added;
    }

0

প্রতিটি কোড টুকরা অবশ্যই কিছু জ্ঞান বহন করতে হবে। আপনি যদি অ্যাপ্লিকেশনের সর্বত্র মান দ্বারা ভাগ করা পয়েন্টারটি পাস করেন তবে এর অর্থ "অন্য কোথাও কী চলছে সে সম্পর্কে আমি নিশ্চিত নই, তাই আমি কাঁচা সুরক্ষার পক্ষে আছি " কোডের সাথে পরামর্শ করতে পারে এমন অন্যান্য প্রোগ্রামারদের আমি এটি একটি ভাল আত্মবিশ্বাসের চিহ্ন বলি না।

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

হ্যাঁ, আইএমও, ডিফল্টটি " কনস্ট রেফারেন্স দ্বারা পাস " হওয়া উচিত ।

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