কেবল ফাংশন ওভারলোডিংয়ের জন্য কোনও সি ++ সংকলক ব্যবহার করা কি খারাপ অভ্যাস?
আইএমএইচও-র অবস্থান, হ্যাঁ, এবং আমি এর উত্তরটির জন্য আমাকে সিজোফ্রেনিক হতে হবে যেহেতু আমি উভয় ভাষা পছন্দ করি তবে এর দক্ষতার সাথে কিছুই করার নেই, তবে ভাষা এবং সুরক্ষার মতো ভাষা ব্যবহারের মতো।
সি সাইড
একটি সি দৃষ্টিকোণ থেকে, আমি আপনার কোডটি কেবল ফাংশন ওভারলোডিং ব্যবহারের জন্য সি ++ প্রয়োজন তা আপনার পক্ষে এটি অপচয় করার মতো মনে হয়। আপনি যদি এটি সি ++ টেমপ্লেটগুলির সাথে স্ট্যাটিক পলিমারফিজমের জন্য ব্যবহার না করেন তবে সম্পূর্ণরূপে ভিন্ন ভাষায় স্যুইচ করার বিনিময়ে এ জাতীয় তুচ্ছ সিনট্যাকটিকাল চিনি অর্জন করা। আরও যদি আপনি কখনও কোনও ডিলিবের কাছে আপনার ফাংশনগুলি রফতানি করতে চান (তবে এটি ব্যবহারিক উদ্বেগ নাও থাকতে পারে), আপনি নাম নামক চিহ্নযুক্ত সমস্ত চিহ্ন সহ বিস্তৃত ব্যবহারের জন্য আর ব্যবহারিকভাবে এত তাড়াতাড়ি করতে পারবেন না।
সি ++ সাইড
একটি সি ++ অবস্থান থেকে, আপনি ফাংশন ওভারলোডিংয়ের সাথে সি এর মতো সি ++ ব্যবহার করবেন না। এটি স্টাইলিস্টিক কৌতুকবাদ নয় বরং এটি প্রতিদিনের সি ++ এর ব্যবহারিক ব্যবহারের সাথে সম্পর্কিত।
আপনার সাধারণ ধরণের সি কোডটি কেবল যুক্তিসঙ্গতভাবে বুদ্ধিমান এবং "নিরাপদ" লিখতে হবে যদি আপনি সি টাইপ সিস্টেমের বিরুদ্ধে কাজ করছেন যা অনুলিপি করণকারীগুলির মতো জিনিসগুলিকে নিষিদ্ধ করে structs
। আপনি একবার সি ++ এর অনেক বেশি সমৃদ্ধ টাইপ সিস্টেমে কাজ করার পরে, প্রতিদিনের ফাংশনগুলি যা প্রচুর পরিমাণে মূল্যবান হয় memset
এবং memcpy
ফাংশনগুলিতে পরিণত হয় না তা আপনাকে সর্বদা ঝুঁকতে হবে। পরিবর্তে, এগুলি এমন ক্রিয়াকলাপ যা আপনি সাধারণত প্লেগের মতো এড়াতে চান, যেহেতু সি ++ প্রকারের মাধ্যমে, আপনি কাঁচা বিট এবং বাইটগুলির মতো অনুলিপি করা এবং চারপাশে এলোমেলো এবং মুক্ত হওয়া উচিত নয়। এমনকি যদি আপনার কোডটি memset
এই মুহুর্তে কেবলমাত্র আদিম এবং পিওডি ইউডিটির মতো জিনিস ব্যবহার করে তবে যে মুহুর্তে আপনার ব্যবহার করা কোনও ইউডিটিতে কোনও সিটার যুক্ত করা হয় (যেমন কোনও সদস্যের প্রয়োজন হয় যার জন্য একটি প্রয়োজন, যেমনstd::unique_ptr
সদস্য) যেমন ফাংশন বা ভার্চুয়াল ফাংশন বা এই ধরণের কোনও কিছুর বিরুদ্ধে, এটি আপনার সমস্ত সাধারণ সি-স্টাইলের কোডিংকে সংজ্ঞায়িত আচরণের জন্য সংবেদনশীল re এটি হার্ব সাটার থেকে নিজে নিন:
memcpy
এবং memcmp
টাইপ সিস্টেম লঙ্ঘন। ব্যবহার memcpy
বস্তু কপি করতে অর্থ উপার্জন একটি photocopier ব্যবহার ভালো হয়। memcmp
বস্তুর তুলনা করতে ব্যবহার করা চিতাগুলির দাগগুলি গণনা করার সাথে তুলনা করার মতো। সরঞ্জামগুলি এবং পদ্ধতিগুলি কাজটি করার মতো হতে পারে তবে এটি গ্রহণযোগ্যভাবে করার জন্য তারা খুব মোটা। সি ++ অবজেক্টগুলি সমস্ত তথ্য গোপনের বিষয়ে রয়েছে (সফটওয়্যার ইঞ্জিনিয়ারিংয়ের পক্ষে সবচেয়ে লাভজনক নীতি; আইটেম 11 দেখুন): অবজেক্টগুলি ডেটা লুকায় (আইটেম 41 দেখুন) এবং কনস্ট্রাক্টর এবং অ্যাসাইনমেন্ট অপারেটরগুলির মাধ্যমে সেই ডেটা অনুলিপি করার জন্য সুনির্দিষ্ট বিমূর্ততা রচনা করেন (আইটেম 52 এর মাধ্যমে 55 দেখুন) । এই সমস্ত কিছুর উপরে বুলডোজিং তথ্য আড়ালকরণের memcpy
মারাত্মক লঙ্ঘন এবং প্রায়শই স্মৃতি এবং সংস্থানসমূহের ফাঁস (সবচেয়ে ভাল), ক্র্যাশ (আরও খারাপ), বা অপরিজ্ঞাত আচরণের (সবচেয়ে খারাপ) - সি ++ কোডিং স্ট্যান্ডার্ডগুলির দিকে পরিচালিত করে।
সুতরাং অনেক সি বিকাশকারী এটির সাথে একমত নন এবং ঠিক তাই, কারণ দর্শণ কেবল তখনই প্রযোজ্য যদি আপনি সি ++ তে কোড লিখছেন। আপনি সম্ভবত হয় খুব সমস্যাযুক্ত কোড লেখা যদি আপনি চান ফাংশন ব্যবহার memcpy
সব সময় কোডে সি ++ যেমন তৈরী করে যে , কিন্তু এটা পুরোপুরি ঠিক আছে যদি আপনি এটা করতে সি । টাইপ সিস্টেমের মধ্যে পার্থক্যের কারণে দুটি ভাষা এই ক্ষেত্রে খুব আলাদা। এই দু'টির সাধারণ বৈশিষ্ট্যগুলির সাবসেটটি দেখার জন্য এটি খুব লোভনীয় এবং বিশ্বাস করে যে একটিতে অন্যটির মতো ব্যবহার করা যেতে পারে, বিশেষত সি ++ পার্শ্বে, তবে সি + কোড (বা সি - কোড) সাধারণত সি এবং উভয়ের চেয়ে অনেক বেশি সমস্যাযুক্ত is সি ++ কোড।
তেমনিভাবে আপনাকে malloc
সি-স্টাইলের প্রসঙ্গে (যা কোনও ইএইচ বোঝায় না) ব্যবহার করা উচিত নয়, যদি এটি সরাসরি কোনও সি ++ ফাংশন কল করতে পারে যা নিক্ষেপ করতে পারে, যেহেতু আপনার ফলস্বরূপ আপনার ফাংশনে একটি অন্তর্নিহিত পয়েন্ট রয়েছে ব্যতিক্রম যা আপনি কার্যকরভাবে সি-স্টাইল কোড রচনা করতে পারবেন না, free
সেই স্মৃতিতে সক্ষম হওয়ার আগে । তাই যখনই আপনি সি একটি সঙ্গে ++, তৈরী করে যে একটি ফাইল আছে .cpp
এক্সটেনশন বা যাই হোক না কেন ও এর মত জিনিস এই সব ধরনের কাজ করে malloc
, memcpy
, memset
,qsort
, ইত্যাদি, তারপর এটি সমস্যাটি আরও লাইনটিতে জিজ্ঞাসা করছে যদি না এটি ইতিমধ্যে যদি না থাকে তবে কেবলমাত্র আদিম ধরণের সাথে কাজ করে এমন একটি শ্রেণীর প্রয়োগের বিবরণ না হয়, যেখানে এখনও ব্যতিক্রম-নিরাপদ হওয়ার জন্য এটি ব্যতিক্রম হ্যান্ডলিংয়ের প্রয়োজন to আপনি সি ++ কোড লেখার তাহলে আপনি যদি এর পরিবর্তে সাধারণত RAII উপর নির্ভর করে এবং ভালো জিনিস ব্যবহার করতে চান vector
, unique_ptr
, shared_ptr
, ইত্যাদি, এবং যখন সম্ভব সব স্বাভাবিক সি-শৈলী কোডিং এড়ানো।
আপনি সি এবং এক্স-রে ডেটা ধরণের রেজার ব্লেডের সাথে খেলতে পারেন এবং কোনও দলে কোলেটারাল ক্ষতির কারণ না হয়ে তাদের বিট এবং বাইটগুলি নিয়ে খেলতে পারেন (যদিও আপনি এখনও উভয় উপায়ে নিজেকে আঘাত করতে পারেন) এটি সি এর কারণ নয় প্রকারগুলি করতে পারে তবে তারা কখনই করতে সক্ষম হবে না তার কারণে। আপনি সি এর টাইপ সিস্টেমকে সি ++, সি, ডিটার এবং ভিটিবেলের মতো বৈশিষ্ট্যগুলি ব্যতিক্রম হ্যান্ডলিংয়ের সাথে অন্তর্ভুক্ত করার মুহুর্তটি সমস্ত ইডিয়োমেটিক সি কোড বর্তমানের চেয়ে অনেক বেশি বিপজ্জনক হিসাবে রেন্ডার করা হবে এবং আপনি নতুন ধরণের দেখতে পাবেন দর্শন এবং মানসিকতা বিকশিত যা কোডিংয়ের সম্পূর্ণ ভিন্ন স্টাইলকে উত্সাহিত করবে, যেমন আপনি সি ++ তে দেখেন যা এখন এমন কোনও শ্রেণীর জন্য কাঁচা পয়েন্টার অপব্যবহারকেও বিবেচনা করে যা স্মৃতি পরিচালনা করে, বলে, একটি RAII- অনুসারে সংস্থান হিসাবে পছন্দ করে না unique_ptr
। সুরক্ষার নিখুঁত ধারণা থেকে সেই মানসিকতা বিকশিত হয়নি। এটা আউট প্রসূত কি সি ++ বিশেষভাবে মত বৈশিষ্ট্য বিরুদ্ধে নিরাপদ করা প্রয়োজন ব্যতিক্রম-হ্যান্ডলিং দেওয়া কি এটা নিছক পারবেন তার টাইপ সিস্টেমের মাধ্যমে।
ব্যতিক্রম-নিরাপত্তা
আবার, আপনি যে মুহূর্তে সি ++ জমিতে রয়েছেন, লোকেরা আপনার কোডটি ব্যতিক্রম-নিরাপদ বলে প্রত্যাশা করছে। লোকেরা ভবিষ্যতে আপনার কোডটি বজায় রাখতে পারে, এটি ইতিমধ্যে লিখিত এবং সি ++ তে সংকলিত হয়েছে এবং std::vector, dynamic_cast, unique_ptr, shared_ptr
আপনার কোড দ্বারা প্রত্যক্ষ বা অপ্রত্যক্ষভাবে বলা কোডে সহজভাবে ব্যবহার ইত্যাদি কোড ব্যবহার করেছে , কারণ আপনার কোডটি ইতিমধ্যে "অনুমিত" সি ++ রয়েছে তাই এটি নির্দোষ বলে বিশ্বাস করে কোড। এই মুহুর্তে আমাদের জিনিসগুলি ফেলে দেওয়ার সম্ভাবনার মুখোমুখি হতে হবে এবং তারপরে আপনি যখন পুরোপুরি সূক্ষ্ম এবং সুন্দর সি কোডটি গ্রহণ করেন:
int some_func(int n, ...)
{
int* x = calloc(n, sizeof(int));
if (x)
{
f(n, x); // some function which, now being a C++ function, may
// throw today or in the future.
...
free(x);
return success;
}
return fail;
}
... এখন ভেঙে গেছে। ব্যতিক্রম-সুরক্ষার জন্য এটি আবার লিখতে হবে:
int some_func(int n, ...)
{
int* x = calloc(n, sizeof(int));
if (x)
{
try
{
f(n, x); // some function which, now being a C++ function, may
// throw today or in the future (maybe someone used
// std::vector inside of it).
}
catch (...)
{
free(x);
throw;
}
...
free(x);
return success;
}
return fail;
}
স্থূল! যে কারণে বেশিরভাগ সি ++ বিকাশকারীরা এর পরিবর্তে এটি দাবি করবে:
void some_func(int n, ...)
{
vector<int> x(n);
f(x); // some function which, now being a C++ function, may throw today
// or in the future.
}
উপরেরটি হ'ল রেআইআই-কনফর্মিং ব্যতিক্রম-নিরাপদ কোডটি যা সি ++ বিকাশকারীরা সাধারণত অনুমোদন করবে যেহেতু ফাংশনটি কোনও ফাঁস করবে না যার ফলে কোন কোডের রেখাটি কোনও ফলাফলের ফলে অন্তর্নিহিত প্রস্থান শুরু করে throw
।
একটি ভাষা চয়ন করুন
আপনি সিআইএসের টাইপ সিস্টেম এবং দর্শনের সাথে আরআইআই, ব্যতিক্রম-সুরক্ষা, টেম্পলেট, ওওপি ইত্যাদির সাহায্যে আলিঙ্গন করতে হবে বা সিটিকে আলিঙ্গন করতে হবে যা মূলত কাঁচা বিট এবং বাইটের চারদিকে ঘোরে। এই দুটি ভাষার মধ্যে আপনার অপরিষ্কার বিবাহ করা উচিত নয় এবং এগুলি একসাথে ঝাপসা করার পরিবর্তে এটিকে আলাদা ভাষায় আলাদা করা উচিত।
এই ভাষাগুলি আপনাকে বিয়ে করতে চায়। আপনি সাধারণত ডেটিং এবং দু'জনের সাথে বোকা বানানোর পরিবর্তে একটি বেছে নেবেন। অথবা আপনি আমার মতো বহুবিবাহবিদ হতে পারেন এবং উভয়কেই বিবাহ করতে পারেন তবে একজনের সাথে একজনের সাথে সময় কাটাতে গিয়ে আপনার চিন্তাভাবনা সম্পূর্ণরূপে পরিবর্তন করতে হবে এবং একে অপরের থেকে ভালভাবে আলাদা থাকতে হবে যাতে তারা একে অপরের সাথে লড়াই না করে।
বাইনারি আকার
কৌতূহলের বাইরে আমি এখনই আমার নিখরচায় তালিকা বাস্তবায়ন এবং বেঞ্চমার্কটি নেওয়ার চেষ্টা করেছি এবং এটি সম্পর্কে C ++ তে পোর্টিং করার পরে যেহেতু আমি এ সম্পর্কে সত্যই কৌতূহল পেয়েছি:
[...] সি এর জন্য দেখতে কেমন তা জানেন না কারণ আমি সি সংকলকটি ব্যবহার করি না।
... এবং জানতে চাইছিল যে বাইনারি আকারটি কেবলমাত্র C ++ হিসাবে বিল্ডিংয়ে উত্সাহিত করবে। এটিকে আমার পুরো জায়গা জুড়ে স্পষ্ট কাস্ট ছড়িয়ে ছিটিয়ে দেওয়া দরকার ছিল যা ছিল পলাতক (একটি কারণ যা আমি আসলে নিম্নতর স্তরের জিনিস যেমন সিতে আরও ভাল বরাদ্দকারী এবং ডেটা স্ট্রাকচার লিখতে পছন্দ করি) তবে কেবল এক মিনিট সময় নিয়েছিল।
এটি কেবলমাত্র একটি সাধারণ কনসোল অ্যাপ্লিকেশনের জন্য এবং এমন কোনও কোডের সাথে একটি এমএসভিসি and৪-বিট রিলিজ বিল্ডের সাথে তুলনা করছিল যা কোনও সি ++ বৈশিষ্ট্য ব্যবহার করে না, এমনকি অপারেটর ওভারলোডিংও নয় - কেবল এটি সি ব্যবহার করে এবং বলার <cstdlib>
পরিবর্তে <stdlib.h>
এবং এর পরিবর্তে , বলুন, এই জাতীয় জিনিস, কিন্তু আমি এটি বাইনারি আকারের থেকে শূন্য পার্থক্য খুঁজে পেয়ে অবাক!
বাইনারিটি 9,728
যখন সিটিতে নির্মিত হয়েছিল তখন বাইটস ছিল এবং 9,278
তেমনিভাবে ব + বাইটগুলি সি ++ কোড হিসাবে সংকলিত করার সময় ছিল। আমি আসলে এটি আশা করিনি। আমি ভেবেছিলাম EH এর মতো জিনিসগুলি সেখানে কমপক্ষে কিছুটা যোগ করবে (ভেবেছিল এটি কমপক্ষে একশ বাইটের মতো আলাদা হবে), যদিও সম্ভবত এটি ঠিক করতে পেরেছেন যে আমি ঠিক যেহেতু ইএইচ-সম্পর্কিত নির্দেশ যুক্ত করার দরকার নেই was সি স্ট্যান্ডার্ড লাইব্রেরি ব্যবহার করে এবং কিছুই ছোঁড়ে না। আমি কিছু ভেবেছিআরটিটিআই-র মতো বাইনারি আকারে কিছুটা হলেও যুক্ত করা হবে। যাইহোক, এটি দেখতে দারুণ লাগছিল। অবশ্যই আমি মনে করি না আপনি এই একটি ফলাফল থেকে সাধারণীকরণ করা উচিত, তবে এটি কমপক্ষে আমাকে কিছুটা মুগ্ধ করেছে। এটি মানদণ্ডগুলিতেও কোনও প্রভাব ফেলেনি এবং স্বাভাবিকভাবেই, যেহেতু আমি কল্পনা করি যে একইরকম ফলস্বরূপ বাইনারি আকারের অর্থ একই রকমের ফলস্বরূপ মেশিনের নির্দেশাবলীও ছিল।
এটি বলেছিল, উপরে বর্ণিত সুরক্ষা এবং প্রকৌশল সংক্রান্ত সমস্যাগুলির সাথে বাইনারি আকারের বিষয়ে কে যত্নশীল? সুতরাং, আবার কোনও ভাষা বেছে নিন এবং এর দর্শনকে জটলা করার পরিবর্তে আলিঙ্গন করুন; এটাই আমি সুপারিশ করি।
//
মন্তব্য করতে পারি । যদি এটি কাজ করে তবে কেন নয়?