ভেক্টরগুলি মান বা সি ++ তে রেফারেন্স দ্বারা ফাংশনে প্রেরণ করা হয়েছে


97

আমি সি ++ তে কোডিং করছি। যদি আমার কিছু ফাংশন থাকে void foo(vector<int> test)এবং আমি আমার প্রোগ্রামে এটি কল করি তবে ভেক্টরটি মান বা রেফারেন্স দিয়ে পাস হবে? আমি নিশ্চিত না কারণ আমি জানি যে ভেক্টর এবং অ্যারেগুলি একই রকম এবং এটির মতো কোনও ফাংশনটি void bar(int test[])মানের পরিবর্তে রেফারেন্স (পয়েন্টার?) দিয়ে পরীক্ষা দেয়। আমার ধারণা হ'ল যদি আমি মান দ্বারা পাস করা এড়াতে চাইতাম তবে স্পষ্টভাবে পয়েন্টার / রেফারেন্স দ্বারা ভেক্টরটি পাস করতে হবে তবে আমি নিশ্চিত নই।


4
সি ++ এর "মূল্য দ্বারা পাস" শব্দার্থবিজ্ঞান রয়েছে, সুতরাং এটি মান দ্বারা পাস করা হয়। আপনি যদিও রেফারেন্স দিয়ে পাস করার সিদ্ধান্ত নিতে পারেন। পছন্দটি আসলে ফাংশনটি কী করে তার উপর নির্ভর করে।
janchopanza

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

4
এছাড়াও, একটি রেফারেন্স কোনও পয়েন্টার নয়।
প্যারাম্যাগনেটিক ক্রোস্যান্ট

4
@ অ্যালিকাজমি ব্যতীত যদি আপনি ফাংশনের মূল অংশটিতে একটি অনুলিপি চান।
juanchopanza

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

উত্তর:


136

যদি আমার অনুমান করতে হয় তবে আমি বলতে পারি যে আপনি জাভা ব্যাকগ্রাউন্ড থেকে এসেছেন। এটি সি ++, এবং জিনিসগুলি মান দ্বারা পাস করা হয় যদি না আপনি অন্যটি-ব্যবহারকারী ব্যবহার করে নির্দিষ্ট না করে &থাকেন (দ্রষ্টব্য যে এই অপারেটরটি 'অ্যাড্রেস-অফ' অপারেটর হিসাবেও ব্যবহৃত হবে, তবে ভিন্ন প্রসঙ্গে)। এটি সমস্ত ভাল নথিবদ্ধ, তবে আমি যাইহোক যাইহোক পুনরায় পুনরাবৃত্তি করব:

void foo(vector<int> bar); // by value
void foo(vector<int> &bar); // by reference (non-const, so modifiable inside foo)
void foo(vector<int> const &bar); // by const-reference

আপনি কোনও ভেক্টর ( void foo(vector<int> *bar)) এর কাছে কোনও পয়েন্টারও পাস করতে বেছে নিতে পারেন , তবে আপনি কী করছেন তা যদি না জানেন এবং আপনি যদি মনে করেন না যে এটি সত্যিই যাবার উপায়, তবে এটি করবেন না।

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

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

void foo1(int *arr) { cout << sizeof(arr) << '\n'; }
void foo2(int arr[]) { cout << sizeof(arr) << '\n'; }
void foo3(int arr[10]) { cout << sizeof(arr) << '\n'; }
void foo4(int (&arr)[10]) { cout << sizeof(arr) << '\n'; }

int main()
{
    int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    foo1(arr);
    foo2(arr);
    foo3(arr);
    foo4(arr);
}

4
কেউ কি আমাকে শেষ ঘোষণার foo4 ফাংশন বুঝতে সাহায্য করতে পারে? এটি অন্যান্য ফাংশনের মতো পয়েন্টারের আকারের পরিবর্তে অ্যারের আকারটি কেন ফিরিয়ে দেয়?
অভিষেক_এম

4
@ অভিষেক_এম কারণ প্যারামিটারের ধরনটি একটি উল্লেখ। একটি রেফারেন্স কেবল ঠিক একই ধরণের অভিব্যক্তিতে আবদ্ধ হতে পারে। এই কারণে অ্যারে ক্ষয় হয় না, কারণ একটি অ্যারের রেফারেন্স কোনও পয়েন্টারের সাথে আবদ্ধ হতে পারে না, এটি কেবল একই ধরণের অ্যারের সাথে আবদ্ধ হতে পারে (এই ক্ষেত্রে 10 পূর্ণসংখ্যার অ্যারে)
বলভ

4
সি ++ 11 এর "মুভ সেমেন্টিকস" রয়েছে এবং আপনি এটি যত্ন সহকারে করতে পারেন এবং কপি ছাড়াই মান দিয়ে (মুভ শব্দার্থিক সহ) পাস করতে পারেন। এখানে একটি লিঙ্ক যা আমাকে অনেক সাহায্য করেছিল: mbevin.wordpress.com/2012/11/20/move-semantics
fchen

24

vectorঅ্যারে হিসাবে কার্যত একই same তবে ভাষার vectorকাছে এক ধরণের এবং intএটিও এক প্রকারের। একটি ফাংশন আর্গুমেন্টের জন্য, যে কোনও ধরণের অ্যারে (সহ vector[]) পয়েন্টার হিসাবে বিবেচনা করা হয়। একটি vector<int>হিসাবে একই নয় int[](কম্পাইলার)। vector<int>অ-অ্যারে, অ-রেফারেন্স এবং অ-পয়েন্টার - এটি মান দ্বারা পাস করা হচ্ছে, এবং তাই এটি অনুলিপি-নির্মাণকারীকে কল করবে।

সুতরাং, আপনাকে অবশ্যই এটি ব্যবহার করতে হবে vector<int>&(অগ্রাধিকার সহ const, যদি ফাংশন এটি সংশোধন না করে তবে) এটি একটি রেফারেন্স হিসাবে পাস করার জন্য।


একটি ফাংশন রেফারেন্স দ্বারা "ভেক্টরের অ্যারে" পাস করার সিনট্যাক্সটি কী?
ab123

অকার্যকর functionName (এসটিডি :: ভেক্টর <int- এ> (& সহঅধিনায়ক) [5]) {}
RIanGillis

9

void foo(vector<int> test)

ভেক্টর এই মান দ্বারা পাস করা হবে।

আপনার প্রসঙ্গের উপর নির্ভর করে ভেক্টরগুলি পাস করার আরও উপায় রয়েছে: -

1) রেফারেন্স দ্বারা পাস করুন: - এটি ফাংশন foo ভেক্টর আপনার বিষয়বস্তু পরিবর্তন করতে দেয়। ভেক্টরের অনুলিপি হিসাবে মান দ্বারা পাসের চেয়ে আরও কার্যকর এড়ানো হয়।

2) কনস্ট্যান্ড-রেফারেন্স দ্বারা পাস: - আপনি ভেক্টরের সামগ্রী পরিবর্তন করতে ফাংশনটি চান না যখন এটি দক্ষ পাশাপাশি নির্ভরযোগ্য।


1

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

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