পার্থক্য: এসটিডি :: রানটাইম_অররোর বনাম এসটিডি :: ব্যতিক্রম ()


127

মধ্যে পার্থক্য কি std::runtime_errorএবং std::exception? প্রতিটি জন্য উপযুক্ত ব্যবহার কি? তারা প্রথম স্থানে আলাদা কেন?

উত্তর:


152

std::exceptionএমন শ্রেণি যাঁর একমাত্র উদ্দেশ্য ব্যতিক্রম শ্রেণিবিন্যাসের বেস ক্লাস হিসাবে পরিবেশন করা। এর অন্য কোন ব্যবহার নেই। অন্য কথায়, ধারণাগতভাবে এটি একটি বিমূর্ত শ্রেণি (যদিও এটি শব্দটির সি ++ অর্থের মধ্যে বিমূর্ত শ্রেণি হিসাবে সংজ্ঞায়িত হয়নি)।

std::runtime_errorstd::exceptionবিভিন্ন রানটাইম ত্রুটির ক্ষেত্রে নিক্ষেপ করার উদ্দেশ্যে উত্সাহিত করা একটি আরও বিশেষ শ্রেণিবদ্ধ শ্রেণী । এটির দ্বৈত উদ্দেশ্য রয়েছে। এটি নিজে নিক্ষিপ্ত হতে পারে, অথবা এটি যেমন রানটাইম এরর ব্যতিক্রম বিভিন্ন আরও বেশি বিশেষ ধরনের, এর একটি বেস শ্রেণী হিসেবে পরিবেশন করা যাবে std::range_error, std::overflow_errorইত্যাদি আপনি আপনার নিজের ব্যতিক্রম শ্রেণীর সাজানো বর্ণনা করতে পারেন std::runtime_error, সেইসাথে আপনি আপনার নিজের ব্যতিক্রম বর্ণনা করতে পারেন ক্লাস থেকে অবতরণ std::exception

ঠিক তেমন std::runtime_error, স্ট্যান্ডার্ড লাইব্রেরিতেও রয়েছে std::logic_error, নেমে আসা std::exception

এই শ্রেণিবিন্যাসের বিষয়টি হ'ল ব্যবহারকারীকে সি ++ ব্যতিক্রম হ্যান্ডলিং প্রক্রিয়াটির সম্পূর্ণ শক্তি ব্যবহারের সুযোগ দেওয়া। যেহেতু 'ক্যাচ' ধারাটি পলিমারফিক ব্যতিক্রমগুলি ধরতে পারে, তাই ব্যবহারকারী 'ক্যাচ' ধারাগুলি ব্যতিক্রম শ্রেণিবদ্ধের একটি নির্দিষ্ট সাবট্রি থেকে ব্যতিক্রম প্রকারগুলি ধরতে পারে write উদাহরণস্বরূপ, সাবট্রি catch (std::runtime_error& e)থেকে সমস্ত ব্যতিক্রম ধরা পড়বে std::runtime_error, অন্য সকলকে দিয়ে যেতে দেবে (এবং কল স্ট্যাকটি আরও উড়ে যাবে)।

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

আপডেট: পোর্টেবিলিটি লিনাক্স বনাম উইন্ডোজ

যেমন লোকি আস্তারি এবং ইউনিক্সমান ৩ below তাদের উত্তর এবং নীচে দেওয়া মন্তব্যে উল্লিখিত হয়েছে, exceptionশ্রেণীর নির্মাতা সি ++ স্ট্যান্ডার্ড অনুযায়ী কোনও যুক্তি গ্রহণ করেন না। মাইক্রোসফ্ট সি ++ এর exceptionক্লাসে যুক্তিযুক্ত কনস্ট্রাক্টর রয়েছে তবে এটি মানক নয়। runtime_errorবর্গ একটি কন্সট্রাকটর গ্রহণ আর্গুমেন্টগুলি (হয়েছে char*উভয় প্লাটফর্ম, উইন্ডোজ এবং লিনাক্স)। পোর্টেবল হতে, আরও ভাল ব্যবহার runtime_error

(এবং মনে রাখবেন, কেবল আপনার প্রকল্পের একটি স্পেসিফিকেশন বলে যে আপনার কোডটি লিনাক্সে চলতে হবে না, এর অর্থ এই নয় যে এটি কখনই লিনাক্সে চালিত হয় না))


1
ধন্যবাদ. দুর্দান্ত উত্তর যদিও আমি ভাবছি যদি কখনও আলাদা ধরণের ব্যতিক্রম হওয়ার প্রয়োজন হয় ... তবে কেবল একটি চিন্তাভাবনা।
শিববধু

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

1
ঠিক যেমন একদিকে: কোনও নিয়ম নেই, কোথাও নেই, যা আপনাকে উত্সাহ দিতে বাধ্য করে std::exception। অবশ্যই, সমস্ত stdজিনিস সেগুলির উত্পন্ন ক্লাস নিক্ষেপ করে তবে কেবল std::exceptionউত্পন্ন বস্তু নিক্ষেপ করার কোনও কারণ নেই ।
রুবেনভিবি

1
@ রুবেনভব আমি সে সম্পর্কে জানতাম না, তবে আমি মনে করি যদি কেবল ব্যতিক্রম থেকে প্রাপ্ত ক্লাসগুলির বস্তুগুলি ফেলে দেওয়া হয় তবে এটি ভবিষ্যতের রক্ষণাবেক্ষণের কোডটি পরিষ্কার করবে। উদাহরণ: আমি আমার কোড বেসে কাস্টম ব্যতিক্রমগুলি প্রয়োগ করা হয় তা খুঁজে পেতে এবং ব্যতিক্রম থেকে প্রাপ্ত ক্লাসগুলির সন্ধান করতে চাই।
this.myself

21

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

std::runtime_errorঅন্যদিকে বৈধ নির্মাণকারী রয়েছে যা একটি বার্তা হিসাবে একটি স্ট্রিং গ্রহণ করে। যখন what()কনস্ট্র্ট চর পয়েন্টার বলা হয় তখন সি স্ট্রিংয়ের বিন্দুতে যে বিন্দুটি কনস্ট্রাক্টরে পাস হয়েছিল একই স্ট্রিংয়ের সাথে ফিরে আসে।

try
{
    if (badThingHappened)
    {
         throw std::runtime_error("Something Bad happened here");
    }
}
catch(std::exception const& e)
{
    std::cout << "Exception: " << e.what() << "\n";
} 

1
উত্তর মার্টিনের জন্য ধন্যবাদ। যাইহোক, আমি উপরে বর্ণিতভাবে একইভাবে std :: ব্যতিক্রম () ব্যবহার করি। যেমন স্টাড :: ব্যতিক্রম () কনস্ট্রাক্টর একটি স্টাডি :: স্ট্রিং () বা কনস্ট চর নিতেও পারে।
শিববধু

14
মান অনুসারে নয়। std :: ব্যতিক্রম একটি কনস্ট্রাক্টর আছে যে কোনও যুক্তি গ্রহণ করে না takes একটি স্ট্যান্ডার্ড :: স্ট্রিং বা সি-স্ট্রিং গ্রহণযোগ্য একটি সংস্করণ ব্যবহারযোগ্য নয় port
মার্টিন ইয়র্ক

10
মাইক্রোসফ্টের কারণে, আমি নিক্ষেপ করতে অভ্যস্ত হয়েছি std::exception(std::string)। এখন আমি বুঝতে পেরেছি যে std::runtime_errorআমার কোডটি লিনাক্সে (জিসিসি) কাজ করতে চাইলে আমাকে অবশ্যই ফেলে দিতে হবে ।
unixman83
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.