আপনি কোন পরিস্থিতিতে সি ++ এ এই প্রকৃতির কোড ব্যবহার করতে চান?
void foo(type *&in) {...}
void fii() {
type *choochoo;
...
foo(choochoo);
}
আপনি কোন পরিস্থিতিতে সি ++ এ এই প্রকৃতির কোড ব্যবহার করতে চান?
void foo(type *&in) {...}
void fii() {
type *choochoo;
...
foo(choochoo);
}
উত্তর:
আপনি যদি পয়েন্টারটি নির্দেশ করছেন সেই বস্তুর পরিবর্তে পয়েন্টারটি পরিবর্তনের প্রয়োজন হয় তবে আপনি রেফারেন্স দিয়ে একটি পয়েন্টারটি পাস করতে চান।
এটি কেন ডাবল পয়েন্টার ব্যবহার করা হয় তার অনুরূপ; পয়েন্টার ব্যবহারের চেয়ে রেফারেন্স ব্যবহার করা কিছুটা নিরাপদ sa
delete
মেমরির অন্য কোনও জায়গায় ব্যবহার করে বা পুনরায় ফিরিয়ে দিতে পারে না? নাকি আমি ভুল পেয়েছি?
[]
অপারেটরটি ওভারলোড করবেন । এর জন্য একটি সম্ভাব্য (এবং প্রকৃতপক্ষে প্রাকৃতিক) স্বাক্ষর হবে const T &operator[](size_t index) const
। তবে আপনিও থাকতে পারতেন T &operator[](size_t index)
। আপনি একই সাথে উভয় থাকতে পারে। পরেরটি আপনাকে পছন্দ মতো কাজ করতে দেয় myArray[jj] = 42
। একই সময়ে, আপনি আপনার ডেটাতে একটি পয়েন্টার সরবরাহ করছেন না, তাই কলার স্মৃতিতে গোলযোগ করতে পারে না (যেমন এটি দুর্ঘটনাক্রমে মুছুন)।
সি ++ প্রোগ্রামারদের 50% তাদের মুদ্রক মুছার পরে পয়েন্টারগুলি বাতিল করতে চান:
template<typename T>
void moronic_delete(T*& p)
{
delete p;
p = nullptr;
}
উল্লেখ ছাড়াই আপনি কেবল পয়েন্টারের স্থানীয় কপি পরিবর্তন করবেন, কলকারীকে প্রভাবিত করবেন না।
paranoid_delete
, তবে কুকুরছানা এটির নামকরণ করে moronic_delete
। তিনি সম্ভবত অন্যান্য 50% এর অন্তর্ভুক্ত) যাইহোক, সংক্ষিপ্ত উত্তরটি হ'ল সেটিংসটি পরে নালার দিকে নির্দেশ করে delete
প্রায় কখনও কার্যকর হয় না (কারণ তাদের যেভাবেই সুযোগের বাইরে চলে যাওয়া উচিত) এবং প্রায়শই "বিনামূল্যে পরে" বাগগুলি সনাক্তকরণকে বাধা দেয়।
delete
সাধারণভাবে বোকা। কুকুরছানা, আমি কিছু গুগল করেছিলাম, কেন মুছুন সম্পূর্ণরূপে অকেজো বলে আমি দেখতে পাচ্ছি না (সম্ভবত আমি খুব ভয়ঙ্কর গুগলারের;))। আপনি কি আরও কিছু ব্যাখ্যা করতে পারেন বা একটি লিঙ্ক সরবরাহ করতে পারেন?
ডেভিডের উত্তরটি সঠিক, তবে এটি যদি এখনও কিছুটা বিমূর্ত হয়, তবে এখানে দুটি উদাহরণ রয়েছে:
মেমরির সমস্যাগুলি আগে পেতে আপনি সমস্ত মুক্ত পয়েন্টার শূন্য করতে চাইতে পারেন। সি-স্টাইল আপনি করতেন:
void freeAndZero(void** ptr)
{
free(*ptr);
*ptr = 0;
}
void* ptr = malloc(...);
...
freeAndZero(&ptr);
সি ++ এ একই কাজ করতে, আপনি এটি করতে পারেন:
template<class T> void freeAndZero(T* &ptr)
{
delete ptr;
ptr = 0;
}
int* ptr = new int;
...
freeAndZero(ptr);
লিঙ্কযুক্ত-তালিকাগুলি নিয়ে কাজ করার সময় - প্রায়শই কেবল পরবর্তী নোডের পয়েন্টার হিসাবে উপস্থাপন করা হয়:
struct Node
{
value_t value;
Node* next;
};
এই ক্ষেত্রে, আপনি খালি তালিকায় sertোকানোর সময় আপনাকে অবশ্যই আগত পয়েন্টারটি অবশ্যই পরিবর্তন করতে হবে কারণ ফলাফলটি NULL
আর পয়েন্টার নয়। এটি এমন একটি ক্ষেত্রে যেখানে আপনি কোনও ফাংশন থেকে বাহ্যিক পয়েন্টারটি সংশোধন করেন, সুতরাং এটির স্বাক্ষরে পয়েন্টারের একটি রেফারেন্স থাকবে:
void insert(Node* &list)
{
...
if(!list) list = new Node(...);
...
}
এই প্রশ্নের একটি উদাহরণ আছে ।
পাশ করা পয়েন্টারের কাছে মেমরি বরাদ্দ করতে ফাংশন সরবরাহ করতে এবং এর আকারটি ফিরিয়ে দিতে আমাকে এই জাতীয় কোড ব্যবহার করতে হয়েছিল কারণ আমার সংস্থাটি এসটিএল ব্যবহার করে আমার "অবজেক্ট" করেছে
int iSizeOfArray(int* &piArray) {
piArray = new int[iNumberOfElements];
...
return iNumberOfElements;
}
এটি দুর্দান্ত নয়, তবে পয়েন্টারটি অবশ্যই রেফারেন্স দিয়ে পাস করতে হবে (বা ডাবল পয়েন্টার ব্যবহার করুন)। যদি তা না হয় তবে মেমোরিটিকে পয়েন্টারের স্থানীয় অনুলিপিতে বরাদ্দ করা হয় যদি এটি মান দ্বারা পাস করা হয় যার ফলে মেমরি ফাঁস হয়।
একটি উদাহরণ হ'ল আপনি যখন পার্সার ফাংশনটি লেখেন এবং পড়ার জন্য এটি উত্স পয়েন্টারটি পাস করেন, যদি ফাংশনটি সেই পয়েন্টারটিকে শেষ চরিত্রের পিছনে এগিয়ে দেয় যা পার্সার দ্বারা সঠিকভাবে স্বীকৃত হয়েছে। কোনও পয়েন্টারের রেফারেন্স ব্যবহার করে তা পরিষ্কার হয়ে যায় যে ফাংশনটি মূল পয়েন্টারটিকে তার অবস্থান আপডেট করার জন্য স্থানান্তরিত করবে।
সাধারণভাবে, আপনি যদি কোনও ফাংশনে কোনও পয়েন্টারটি পাস করতে চান তবে আপনি পয়েন্টারগুলিতে রেফারেন্স ব্যবহার করেন এবং আসল পয়েন্টারটিকে মূলটি প্রভাবিত না করে কেবল একটি অনুলিপি সরিয়ে না দেওয়ার পরিবর্তে এটি অন্য কোনও অবস্থানে নিয়ে যেতে দিন ।
আপনি যখন এটির প্রয়োজন হতে পারে তখন অন্য একটি পরিস্থিতি হ'ল যদি আপনার কাছে পয়েন্টার সংগ্রহ থাকে এবং স্টিল অ্যালগরিদম ব্যবহার করে সেগুলি পরিবর্তন করতে চান। সি ++ 98 এ for_each এর উদাহরণ।
struct Storage {
typedef std::list<Object*> ObjectList;
ObjectList objects;
void change() {
typedef void (*ChangeFunctionType)(Object*&);
std::for_each<ObjectList::iterator, ChangeFunctionType>
(objects.begin(), objects.end(), &Storage::changeObject);
}
static void changeObject(Object*& item) {
delete item;
item = 0;
if (someCondition) item = new Object();
}
};
অন্যথায়, যদি আপনি চেঞ্জঅবজেক্ট (অবজেক্ট * আইটেম) স্বাক্ষর ব্যবহার করেন তবে আপনার পয়েন্টারের অনুলিপি রয়েছে, মূলটি নয়।