নিক্ষেপ নতুন এসডি :: ব্যতিক্রম থ্রো স্টাড :: ব্যতিক্রম


113

কিছু কোড দেখার সময় আমি হোঁচট খেয়েছি:

throw /*-->*/new std::exception ("//...

এবং আমি সর্বদা ভাবতাম যে আপনার দরকার নেই / আপনার newএখানে ব্যবহার করা উচিত নয় ।
সঠিক উপায়টি কী, উভয়ই ঠিক আছে, যদি কোনও পার্থক্য থাকে?

পাওয়ারশেল বুস্টের সাহায্যে "গ্রেপিং" করার সময় আমি যা দেখতে পাচ্ছি তা থেকে বিটিডাব্লু কখনই ব্যবহার করে না throw new

পিএস এছাড়াও আমি ব্যবহার করে এমন কিছু সিএলআই কোড পেয়েছি throw gcnew। এটা কি ঠিক আছে?


1
আমি মনে করি throw gcnewদরকারী যেমন। আপনি যদি ব্যতিক্রমটি ধরতে পরিচালিত কোড চান। কেউ কি আমাকে এটি সংশোধন করতে পারেন?
jpalecek

1
। নেট পয়েন্টার দ্বারা ব্যতিক্রম নিয়ে কাজ করে, তাই gcnew নিক্ষেপ করা সেখানে করণীয় সঠিক জিনিস।
সেবাস্তিয়ান রেডল

1
@ সেবাস্তিয়ানআরডেল। নেট "পয়েন্টার" দ্ব্যর্থক হতে পারে? যদিও gcnew অবশ্যই না। System::Exceptionসাধারণত আবর্জনা সংগ্রহ করা স্তূপের উপর পরিচালিত কোনও সামগ্রীর একটি উল্লেখ। আমি সবসময় সঙ্গে নিক্ষেপ করেছি gcnewএবং ধরেছি System::Exception ^। অবশ্যই আমি finallyসি ++ / সিএলআই-তেও সব সময় ব্যবহার করি , যদিও প্রায়শই একই tryব্লকের সি ++ ব্যতিক্রমগুলির সাথে মেশানো হয় না, তবে আমি নিশ্চিত নই কেন।

উত্তর:


89

ব্যতিক্রম ছোঁড়ার এবং ধরার প্রচলিত উপায় হ'ল একটি ব্যতিক্রম বস্তু নিক্ষেপ করা এবং এটি রেফারেন্সের মাধ্যমে ধরা (সাধারণত constরেফারেন্স)। সি ++ ভাষার ক্ষেত্রে ব্যতিক্রমী অবজেক্টটি তৈরি করতে এবং উপযুক্ত সময়ে এটি সঠিকভাবে পরিষ্কার করার জন্য উপযুক্ত কোড উত্পন্ন করার জন্য সংকলকটির প্রয়োজন।

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

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

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


1
"একটি ব্যতিক্রম বস্তু নিক্ষেপ" স্ট্যাক বা আমার বন্ধু গাদা? স্তূপ বা গাদা? (সম্ভবত আমি কোথাও কোনও খারাপ বৈশ্বিক উদাহরণ দেখছিলাম) ওহ এবং যদি স্ট্যাক থাকে তবে উপযুক্ত সুযোগটি কী?

@ ইবাইরব: আপনি কী জিজ্ঞাসা করছেন তা আমি সত্যিই নিশ্চিত নই তবে মনে হয় আপনি স্টোরেজ এবং / অথবা ব্যতিক্রমী অবজেক্টের জীবনকাল সম্পর্কে জানতে চান যা এখানে উত্তর দেওয়া যেতে পারে । না হলে আপনি আলাদা প্রশ্ন জিজ্ঞাসা করা ভাল হতে পারে।
সিবি বেইলি

31

newব্যতিক্রম নিক্ষেপ করার সময় ব্যবহার করার দরকার নেই ।

শুধু লেখো:

throw yourexception(yourmessage);

এবং হিসাবে ধরা:

catch(yourexception const & e)
{
      //your code (probably logging related code)
}

নোট যা প্রত্যক্ষ বা পরোক্ষভাবে yourexceptionপ্রাপ্ত হওয়া উচিত std::exception


7
কেন? কেন ব্যবহার newকরবেন না ? কেন থেকে yourexceptionপ্রাপ্ত std::exception?
ওয়াল্টার

যখন আমি অলস হই (যা প্রায়শই ওয়ায়ে থাকে) কেন throw std::exception;কাজ করে না ? g ++ এটি সংকলন করে বলে মনে হচ্ছে না ...

7
@ebyrob: std::exceptionএটি একটি প্রকার, এবং আপনি কোনও প্রকার ছুঁড়ে ফেলতে পারবেন না , আপনাকে কোনও জিনিস ফেলে দিতে হবে । সুতরাং বাক্য গঠনটি এমন হওয়া উচিত: throw std::exception();এটি সংকলন করবে। এখন এটি কতটা ভাল, তা সম্পূর্ণ আলাদা একটি প্রশ্ন।
নওয়াজ

22

নিক্ষেপ new std::exceptionসঠিক যদি কল সাইটে একটি ধরতে আশা করা হয় std::exception*। তবে কেউই ব্যতিক্রমের পয়েন্টার ধরার প্রত্যাশা করবে না। এমনকি যদি আপনার ডকুমেন্টটি এমনটি ঘটে যা আপনার ফাংশনটি করে এবং লোকেরা ডকুমেন্টেশন পড়ে, তারা এখনও ভুলতে বাধ্য হয় এবং std::exceptionপরিবর্তে কোনও অবজেক্টের রেফারেন্স ধরার চেষ্টা করে।


27
থ্রোইংটি new std::exceptionকেবলমাত্র সঠিক যদি কল সাইটটি কোনও পয়েন্টার ধরার প্রত্যাশা করে এবং বরাদ্দ ব্যতিক্রম পরিচালনা পরিচালনা করার প্রত্যাশা করে এবং আপনার ফাংশনটি এমন কোনও কিছু দ্বারা ডাকা হবে যা স্পষ্টভাবে ধরা দেয় না এমন কোনও ক্ষেত্রেই হবে না are সঠিক পয়েন্টার ( catch(...)বা কোনও কিছুই পরিচালনা করছে না) অন্যথায় একটি অবজেক্ট ফাঁস হবে। সংক্ষেপে, এটি "কখনই নয়" হিসাবে অনুমান করা যেতে পারে।
সিবি বেইলি

এটি আগ্রহী যে এই উত্তরটি কীভাবে গৃহীত হয়েছিল, যখন এটি সত্যিই @ চার্লসবাইলির মন্তব্য যা সঠিক উত্তর।
জন ডিবলিং

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

চার্লস তার উত্তর সরবরাহ করেনি, এবং এই এ (অন্যটির মতো নয়) এ এবং মন্তব্য উভয় ক্ষেত্রেই ব্যাখ্যা রয়েছে।
NoSenseEtAl

9

সি ++ এফএকিউ এর একটি সুন্দর আলোচনা আছে:

  1. https://isocpp.org/wiki/faq/exceptions#what-to-catch
  2. https://isocpp.org/wiki/faq/exceptions#catch-by-ptr-in-mfc

মূলত "যদি না থাকে তবে রেফারেন্স অনুসারে ধরা না দেওয়ার উপযুক্ত কারণ নেই। মূল্য অনুসারে ধরা থেকে বিরত থাকুন কারণ এটি অনুলিপি তৈরি করার কারণ এবং অনুলিপিটি নিক্ষেপিত হওয়া থেকে আলাদা আচরণ করতে পারে Only কেবলমাত্র খুব বিশেষ পরিস্থিতিতে আপনাকে পয়েন্টার দ্বারা ধরা উচিত। "


2
যথারীতি প্রায়শই জিজ্ঞাসিত প্রশ্নগুলি খারাপভাবে শব্দ করা হয়। আপনি মান বা রেফারেন্স দ্বারা ধরতে পারেন। একটি পয়েন্টারটি কেবল একটি মান হিসাবে ঘটে (যা আপনি মান বা রেফারেন্স দ্বারা ধরেন)। মনে রাখবেন প্রকারটি টাইপ Aথেকে স্বতন্ত্র, A*তাই যদি আমি এটি throw A()করি catch(A* e)তবে এটি সম্পূর্ণরূপে ভিন্ন ধরণের হিসাবে আমি ধরতে পারি না ।
মার্টিন ইয়র্ক

এই লিঙ্কগুলি এখন ভেঙে গেছে।
স্টেফেনস্পান

1
আমি লিঙ্কগুলি @ স্প্যানডেমিক
ইউজার 1202136

1

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

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