মান দ্বারা পাস করা বা ধ্রুবক রেফারেন্স দিয়ে পাস করা কি সি ++ তে ভাল?


213

মান দ্বারা পাস করা বা ধ্রুবক রেফারেন্স দিয়ে পাস করা কি সি ++ তে ভাল?

আমি ভাবছি যা ভাল অনুশীলন হয়। আমি বুঝতে পারি যে ধ্রুবক রেফারেন্স দ্বারা পাস প্রোগ্রামে আরও ভাল পারফরম্যান্সের জন্য সরবরাহ করা উচিত কারণ আপনি ভেরিয়েবলের একটি অনুলিপি তৈরি করছেন না।


উত্তর:


203

সাধারণভাবে সেরা অনুশীলনের সুপারিশ হত 1 থেকে জন্য const সুত্র দ্বারা ব্যবহারের পাস সব ধরনের , ধরনের (builtin ছাড়া char, int, double, ইত্যাদি), iterators জন্য এবং ফাংশন অবজেক্টের জন্য (lambdas থেকে আহরিত শ্রেণীর std::*_function)।

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

সি ++ 11 এর সাথে আমরা মুভ সিমানটিকস অর্জন করেছি । সংক্ষেপে, শব্দার্থবিজ্ঞানের অনুমতিটি স্থানান্তর করুন যে কোনও কোনও ক্ষেত্রে কোনও বস্তু অনুলিপি না করেই "মান দ্বারা" পাস করা যায়। বিশেষত, এটি তখন ঘটে যখন আপনি যে অবজেক্টটি দিয়ে যাচ্ছেন সেটি কোনও মূল্য রয়েছে

নিজেই, কোনও বস্তুকে সরিয়ে নেওয়া এখনও উল্লেখ হিসাবে পাস করার মতো কমপক্ষে ব্যয়বহুল। যাইহোক, অনেক ক্ষেত্রে কোনও ফাংশন অভ্যন্তরীণভাবে যে কোনও উপায়ে অনুলিপি করবে - যেমন এটি যুক্তির মালিকানা গ্রহণ করবে । 2

এই পরিস্থিতিতে আমাদের নিম্নলিখিত (সরলীকৃত) বাণিজ্য বন্ধ রয়েছে:

  1. আমরা রেফারেন্স দ্বারা অবজেক্টটি পাস করতে পারি, তারপরে অভ্যন্তরীণভাবে অনুলিপি করতে পারি।
  2. আমরা মান দিয়ে বস্তুটি পাস করতে পারি।

"মান দ্বারা পাস" এখনও অবজেক্টটি অনুলিপি করে তোলে, যদি না অবজেক্টটির মূল্য হয়। কোনও মূল্যমানের ক্ষেত্রে, বস্তুটি পরিবর্তে সরানো যেতে পারে, যাতে দ্বিতীয় কেস হঠাৎ করে "অনুলিপি না করে, পরে সরান" তবে "সরান, তারপরে (সম্ভাব্য) আবার সরানো হবে"।

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


একটি noteতিহাসিক নোট:

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

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

তবে সাধারণভাবে সংকলক এটি নির্ধারণ করতে পারে না, এবং সি ++ এ মুভ সিমানটিক্সের আবিষ্কারটি এই অপ্টিমাইজেশনটিকে অনেক কম প্রাসঙ্গিক করেছে।


স্কট মেয়ার্সে 1 উদাহরণস্বরূপ, কার্যকর সি ++

2 এটি প্রায়শই অবজেক্ট কনস্ট্রাক্টরদের ক্ষেত্রে সত্য, যা আর্গুমেন্ট নিতে পারে এবং এগুলি অভ্যন্তরীণভাবে নির্ধারিত অবজেক্টের রাজ্যের অংশ হতে পারে store


হুমমম ... আমি নিশ্চিত নই যে রেফ দিয়ে যাওয়ার মতো মূল্য আছে is ডাবল-এস
সার্জটেক

3
যথারীতি, বুস্ট এখানে সহায়তা করে। boost.org/doc/libs/1_37_0/libs/utility/call_traits.htm কোনও টাইপ একটি বিল্টিন টাইপ (টেমপ্লেটগুলির জন্য দরকারী, যেখানে আপনি কখনও কখনও সহজে সহজে বুঝতে পারবেন না) তা স্বয়ংক্রিয়ভাবে নির্ধারণ করার জন্য টেমপ্লেট স্টাফ রয়েছে।
সিজারবি

13
এই উত্তরটি একটি গুরুত্বপূর্ণ পয়েন্ট মিস করে। কাটা কাটা এড়াতে, আপনাকে অবশ্যই রেফারেন্স দিয়ে যেতে হবে (কনস্ট বা অন্যথায়)। দেখুন stackoverflow.com/questions/274626/...
ChrisN

6
@ ক্রিস: ঠিক আছে। পলিমারফিজমের পুরো অংশটি আমি ছেড়ে দিয়েছি কারণ এটি সম্পূর্ণ আলাদা শব্দার্থক। আমি বিশ্বাস করি যে ওপি (শব্দার্থিকভাবে) অর্থ "মূল্য দিয়ে" যুক্তি পাস করা। যখন অন্যান্য শব্দার্থবিজ্ঞানের প্রয়োজন হয়, প্রশ্নটি নিজেই পোজ দেয় না।
কনরাড রুডল্ফ

98

সম্পাদনা করুন: সিপিসি-তে ডেভ আব্রাহামসের নতুন নিবন্ধ:

গতি চান? মান দ্বারা পাস।


স্ট্রাইকগুলির মান দ্বারা পাস করুন যেখানে অনুলিপিটি সস্তা, অতিরিক্ত সুবিধা রয়েছে যা সংকলকটি ধরে নিতে পারে যে অবজেক্টগুলি অ্যালাম নয় (একই জিনিস নয়)। পাস-রেফারেন্স ব্যবহার করে সংকলকটি সর্বদা এটি ধরে নিতে পারে না। সাধারণ উদাহরণ:

foo * f;

void bar(foo g) {
    g.i = 10;
    f->i = 2;
    g.i += 5;
}

সংকলক এটি এটিকে অনুকূল করতে পারে

g.i = 15;
f->i = 2;

যেহেতু এটি জানে যে চ এবং জি একই অবস্থান ভাগ করে না। যদি জি একটি রেফারেন্স (foo &) হয়, সংকলক এটি ধরে নিতে পারত না। যেহেতু জিআই তখন f-> i দ্বারা অ্যালাইজড হতে পারে এবং এর মান 7. হতে হবে তাই সংকলকটির জন্য মেমরি থেকে জি-র নতুন মানটি আনতে হবে।

আরও বাস্তব নিয়মের জন্য, মুভ কনস্ট্রাক্টর্টর নিবন্ধে (অত্যন্ত প্রস্তাবিত পড়া) খুব ভাল নিয়ম রয়েছে ।

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

উপরের "প্রিমিটিভ" এর অর্থ মূলত ছোট তথ্য প্রকার যা কয়েকটি বাইট দীর্ঘ এবং বহুবর্ষক (পুনরাবৃত্তকারী, ফাংশন অবজেক্টস, ইত্যাদি ...) বা অনুলিপি করার জন্য ব্যয়বহুল নয়। সেই কাগজে আরও একটি নিয়ম রয়েছে। ধারণাটি হ'ল কখনও কখনও একটি অনুলিপি তৈরি করতে চায় (তর্কটি সংশোধন করা যায় না এমন ক্ষেত্রে) এবং কখনও কখনও কেউ চায় না (যদি কেউ কোনওভাবেই যুক্তিটি অস্থায়ী হলে ফাংশনে আর্গুমেন্টটি ব্যবহার করতে চায়) , উদাহরণ স্বরূপ). কীভাবে এটি করা যেতে পারে তা কাগজটি বিশদভাবে ব্যাখ্যা করে। সি ++ ১ এক্সে সেই কৌশলটি ভাষার সমর্থন সহ স্থানীয়ভাবে ব্যবহার করা যেতে পারে। ততক্ষণ পর্যন্ত আমি উপরের নিয়মগুলি নিয়ে যাব।

উদাহরণস্বরূপ: একটি স্ট্রিং বড় হাতের অক্ষর তৈরি করতে এবং বড় হাতের সংস্করণটি ফিরিয়ে আনার জন্য, সর্বদা মান দ্বারা পাস করা উচিত: যে কোনওভাবেই এর একটি অনুলিপি নিতে হবে (যে কেউ সরাসরি কনস্টের রেফারেন্সটি পরিবর্তন করতে পারে না) - তাই এটি যতটা সম্ভব স্বচ্ছ করুন কলার এবং সেই অনুলিপিটি তাড়াতাড়ি তৈরি করুন যাতে কলার যতটা সম্ভব অপ্টিমাইজ করতে পারে - সেই কাগজে বিস্তারিত বলা হয়েছে:

my::string uppercase(my::string s) { /* change s and return it */ }

তবে আপনার যদি যাইহোক প্যারামিটারটি পরিবর্তন করার প্রয়োজন না হয় তবে কনস্টের উল্লেখ করে এটি নিন:

bool all_uppercase(my::string const& s) { 
    /* check to see whether any character is uppercase */
}

যাইহোক, যদি আপনি প্যারামিটারের উদ্দেশ্যটি আর্গুমেন্টে কিছু লিখতে চান তবে এটি অ-নিরপেক্ষ রেফারেন্স দিয়ে পাস করুন

bool try_parse(T text, my::string &out) {
    /* try to parse, write result into out */
}

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

জোহানেস: আমি পছন্দ যে নিবন্ধটি যখন আমি এটা পড়তে, কিন্তু আমি হতাশ হয় যখন আমি চেষ্টা করছিল। এই কোডটি জিসিসি এবং এমএসভিসি উভয় ক্ষেত্রেই ব্যর্থ হয়েছিল। আমি কি কিছু মিস করেছি, বা এটি বাস্তবে কার্যকর হয় না?
ব্যবহারকারী541686

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

2
মেহরদাদ, আপনি কী প্রত্যাশা করেছিলেন তা নিশ্চিত নন, তবে কোডটি প্রত্যাশার মতো কাজ করে
অয়ন টোডেরেল

আমি কেবল এই সংকলককে বোঝাতে কপি করার প্রয়োজনীয়তাটি বিবেচনা করব যে প্রকারগুলি ভাষার কোনও অভাবকে অতিক্রম করতে পারে না। আমি __restrict__অতিরিক্ত কপি করার চেয়ে বরং জিসিসির (যা রেফারেন্সগুলিতেও কাজ করতে পারে) ব্যবহার করব। খুব খারাপ মান সি ++ C99 এর restrictকীওয়ার্ডটি গ্রহণ করে নি ।
রুসলান

12

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


নেটিভ জাতীয় প্রকারের জন্য, আপনি (সংকলক কোডটি কীভাবে অনুকূলিত করে তার উপর নির্ভর করে) কেবলমাত্র রেফারেন্সের পরিবর্তে কনস্টের রেফারেন্স ব্যবহার করে পারফরম্যান্স বৃদ্ধি পেতে পারেন।
ওজে।

9

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

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

আপনি যদি টেমপ্লেট প্রোগ্রামিং করে থাকেন তবে সাধারণত আপনাকে সর্বদা কনস্ট রেফ দিয়ে যেতে বাধ্য করা হয় কারণ আপনি কী ধরণের পাস করছিলেন তা জানেন না value মান দ্বারা খারাপ কিছু পাস করার জন্য জরিমানা বিল্ট-ইন টাইপ পাসের জরিমানার চেয়েও খারাপ are কনস্ট রেফ দ্বারা


পরিভাষায় নোট: মিলিয়ন ইনট যুক্ত স্ট্রাক্ট এখনও একটি "পিওডি টাইপ"। সম্ভবত আপনি বোঝাতে চাইছেন অন্তর্নির্মিত ধরণের জন্য মান দ্বারা পাস করা ভাল best
স্টিভ জেসোপ

6

নন-টেম্পলেট ফাংশনটির ইন্টারফেস ডিজাইন করার সময় আমি সাধারণত এটি কাজ করি:

  1. ফাংশনটি প্যারামিটারটি সংশোধন করতে না চাইলে এবং মানটি কপি করা (সস্তা, ডাবল, ভাসমান, চর, বুল ইত্যাদি) সুলভ হলে মান দ্বারা পাস করুন ... লক্ষ করুন যে স্ট্যান্ড :: স্ট্রিং, স্টাড :: ভেক্টর এবং বাকীটি স্ট্যান্ডার্ড লাইব্রেরিতে থাকা পাত্রে নেই)

  2. মানটি অনুলিপি করার জন্য কনস্ট পয়েন্টার দিয়ে পাস করুন এবং ফাংশনটি নির্দেশিত মানটি পরিবর্তন করতে চায় না এবং NULL এমন একটি মান যা ফাংশন হ্যান্ডল করে।

  3. যদি মানটি অনুলিপি করা ব্যয়বহুল হয় এবং ফাংশনটি নির্দেশিত মানটি সংশোধন করতে চায় এবং NUL এমন একটি মান যা ফাংশন পরিচালনা করে।

  4. কনডেন্ট রেফারেন্স দিয়ে পাস করুন যখন মানটি অনুলিপি করা ব্যয়বহুল এবং ফাংশনটি উল্লেখ করা মানটি পরিবর্তন করতে চায় না এবং পরিবর্তে কোনও পয়েন্টার ব্যবহার করা হলে NULL একটি বৈধ মান হবে না।

  5. যখন মানটি অনুলিপি করা ব্যয়বহুল হয় এবং ক্রিয়াটি উল্লেখ করা মানটি পরিবর্তন করতে চায় এবং পরিবর্তে কোনও পয়েন্টার ব্যবহার করা হয় তবে NULL একটি বৈধ মান হবে না।


যোগ std::optionalছবি প্রয়োজন এবং আপনি আর পয়েন্টার প্রয়োজন।
ভায়োলেট জিরাফ

5

আপনার উত্তর পেয়েছে বলে মনে হচ্ছে। মান দ্বারা পাস করা ব্যয়বহুল, তবে আপনার প্রয়োজনের সাথে কাজ করার জন্য একটি অনুলিপি দেয়।


আমি নিশ্চিত নই যে কেন এটিকে ভোট দেওয়া হয়েছিল? এটা আমাকে সচেতন করেছে. আপনার যদি বর্তমানে সঞ্চিত মান প্রয়োজন হয় তবে মানটি দিয়ে পাস করুন। যদি তা না হয় তবে রেফারেন্সটি পাস করুন।
কুট্টি

4
এটি সম্পূর্ণ টাইপ নির্ভরশীল। রেফারেন্স অনুসারে একটি পিওডি (প্লেইন পুরাতন ডেটা) টাইপ করা প্রকৃতপক্ষে আরও মেমরি অ্যাক্সেসের কারণে কর্মক্ষমতা হ্রাস করতে পারে।
টরল্যাক

1
স্পষ্টতই রেফারেন্স দিয়ে ইন্ট পাস করা কিছু সংরক্ষণ করে না! আমি মনে করি প্রশ্নটি এমন জিনিসগুলিকে বোঝায় যা পয়েন্টারের চেয়ে বড়।
গিকিমনকি

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

4

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


যদি আপনাকে প্যারামিটারটির কলির অনুলিপিটি সংশোধন করতে হয় তবে আপনি মান দ্বারা পাস করার পরিবর্তে কল কোডটিতে একটি অনুলিপি তৈরি করতে পারেন। IMO আপনার সাধারণত এ জাতীয় বাস্তবায়ন বিশদের উপর ভিত্তি করে এপিআই নির্বাচন করা উচিত নয়: কলিং কোডের উত্স উভয় উপায়েই একই, তবে এর অবজেক্ট কোডটি নয়।
স্টিভ জেসোপ

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

1

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


আমার বোধগম্যতা হ'ল std::vectorআসলে এটির আইটেমগুলি গাদাতে বরাদ্দ করে এবং ভেক্টর অবজেক্টটি নিজে কখনও বৃদ্ধি পায় না। অপেক্ষা কর. যদি অপারেশনের ফলে ভেক্টরের একটি অনুলিপি তৈরি হয় তবে এটি আসলে সমস্ত উপাদানকে নকল করে। এটা খারাপ হবে।
স্টিভেন লু

1
হ্যাঁ, এটাই আমি ভাবছিলাম। sizeof(std::vector<int>)ধ্রুবক, তবে মান অনুসারে এটি পাসওয়ার্ডগুলি এখনও কোনও সংকলক চালাকতার অনুপস্থিতিতে অনুলিপি করবে।
পিটার

1

ছোট ধরণের জন্য মান দ্বারা পাস।

বড় ধরণের জন্য কনস্ট্যান্ড রেফারেন্সগুলি পাস করুন (মেশিনগুলির মধ্যে বিগের সংজ্ঞা পৃথক হতে পারে) তবে C ++ 11 এ, আপনি যদি ডেটা গ্রাস করতে যাচ্ছেন তবে মান দ্বারা পাস করুন, যেহেতু আপনি সরানো শব্দার্থবিজ্ঞানের শোষণ করতে পারেন। উদাহরণ স্বরূপ:

class Person {
 public:
  Person(std::string name) : name_(std::move(name)) {}
 private:
  std::string name_;
};

এখন কলিং কোডটি করত:

Person p(std::string("Albert"));

এবং শুধুমাত্র একটি অবজেক্ট তৈরি করা হত এবং সরাসরি name_শ্রেণিতে সদস্য হিসাবে সরানো হত Person। আপনি যদি কনস্টেন্ট রেফারেন্স দিয়ে পাস করেন তবে এটির জন্য একটি অনুলিপি তৈরি করতে হবে name_


-5

সাধারণ পার্থক্য: - ফাংশনে আমাদের ইনপুট এবং আউটপুট প্যারামিটার রয়েছে, সুতরাং আপনার পাসিং ইনপুট এবং আউট প্যারামিটার যদি একই হয় তবে রেফারেন্সির মাধ্যমে কলটি ব্যবহার করুন যদি ইনপুট এবং আউটপুট পরামিতি আলাদা হয় তবে মান অনুসারে কল ব্যবহার করা ভাল।

উদাহরণ void amount(int account , int deposit , int total )

ইনপুট প্যারামিটার: অ্যাকাউন্ট, আমানত আউটপুট পরামিতি: মোট

ইনপুট এবং আউট ভোল দ্বারা পৃথক ব্যবহার কল

  1. void amount(int total , int deposit )

মোট জমা জমা আউটপুট মোট

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