অপারেটর ওভারলোডিং সম্পর্কে অনেকগুলি পোস্ট অভিযোগ করছে।
আমি অনুভব করেছি যে আমাকে "অপারেটর ওভারলোডিং" ধারণাটি পরিষ্কার করতে হবে, এই ধারণার বিকল্প বিকল্পটি উপস্থাপন করার জন্য।
কোড অবরুদ্ধ?
এই যুক্তি একটি ভ্রান্তি।
সমস্ত ভাষায় অবরুদ্ধ করা সম্ভব ...
অপারেটর ওভারলোডের মাধ্যমে সি ++ তে যেমন ফাংশন / পদ্ধতিতে সি বা জাভাতে কোড অবলম্বন করা সহজ তত সহজ:
// C++
T operator + (const T & a, const T & b) // add ?
{
T c ;
c.value = a.value - b.value ; // subtract !!!
return c ;
}
// Java
static T add (T a, T b) // add ?
{
T c = new T() ;
c.value = a.value - b.value ; // subtract !!!
return c ;
}
/* C */
T add (T a, T b) /* add ? */
{
T c ;
c.value = a.value - b.value ; /* subtract !!! */
return c ;
}
... এমনকি জাভা স্ট্যান্ডার্ড ইন্টারফেসে
অন্য উদাহরণের জন্য, জাভাতে Cloneable
ইন্টারফেসটি দেখুন :
আপনার এই ইন্টারফেসটি প্রয়োগকারী অবজেক্টটি ক্লোন করার কথা। তবে আপনি মিথ্যা বলতে পারেন। এবং একটি ভিন্ন অবজেক্ট তৈরি করুন। প্রকৃতপক্ষে, এই ইন্টারফেসটি এতটাই দুর্বল যে আপনি কেবল অন্য ধরণের জিনিসটি কেবল মজাদার জন্য ফিরে আসতে পারেন:
class MySincereHandShake implements Cloneable
{
public Object clone()
{
return new MyVengefulKickInYourHead() ;
}
}
Cloneable
ইন্টারফেসটি যেমন আপত্তিজনক / আপত্তিজনকভাবে ব্যবহার করা যেতে পারে, তখন কি একই ভিত্তিতে সি ++ অপারেটর ওভারলোডিং নিষিদ্ধ করা উচিত?
দিনের ক্লান্তিকর ঘন্টাটি ফিরিয়ে আনতে আমরা toString()
কোনও MyComplexNumber
শ্রেণীর পদ্ধতিটি ওভারলোড করতে পারি। করা উচিত toString()
ওভারলোডিং খুব নিষিদ্ধ করা? আমরা MyComplexNumber.equals
এলোমেলো করে দিতে পারি এটি এলোমেলো মান ফিরিয়ে আনতে, অপারেশনগুলিকে পরিবর্তন করতে পারে ... ইত্যাদি ইত্যাদি।
জাভাতে, সি ++ বা যে কোনও ভাষা হিসাবে, কোড লেখার সময় প্রোগ্রামারকে ন্যূনতম শব্দার্থকে সম্মান করতে হবে। এর অর্থ হ'ল একটি add
ফাংশন এবং সংযোজন Cloneable
পদ্ধতি যা ক্লোন করে এবং ++
ইনক্রিমেন্টের চেয়ে অপারেটর কার্যকর করে implementing
যাইহোক হতাশ কি?
এখন যেহেতু আমরা জানি যে প্রাথমিক জাভা পদ্ধতির মাধ্যমেও কোডটিকে নাশকতা করা যেতে পারে, আমরা সি ++ এ অপারেটর ওভারলোডিংয়ের আসল ব্যবহার সম্পর্কে নিজেকে জিজ্ঞাসা করতে পারি?
পরিষ্কার এবং প্রাকৃতিক স্বরলিপি: পদ্ধতি বনাম অপারেটর ওভারলোডিং?
আমরা জাভা এবং সি ++ এর "একই" কোডটি নীচের সাথে তুলনা করব, কোন ধরণের কোডিং শৈলীটি পরিষ্কার of
প্রাকৃতিক তুলনা:
// C++ comparison for built-ins and user-defined types
bool isEqual = A == B ;
bool isNotEqual = A != B ;
bool isLesser = A < B ;
bool isLesserOrEqual = A <= B ;
// Java comparison for user-defined types
boolean isEqual = A.equals(B) ;
boolean isNotEqual = ! A.equals(B) ;
boolean isLesser = A.comparesTo(B) < 0 ;
boolean isLesserOrEqual = A.comparesTo(B) <= 0 ;
দয়া করে নোট করুন যে যতক্ষণ অপারেটর ওভারলোড সরবরাহ করা হয় ততক্ষণ এ এবং বি সি ++ তে যে কোনও ধরণের হতে পারে। জাভাতে, যখন এ এবং বি আদিম নয়, কোডটি খুব বিভ্রান্তিকর হয়ে উঠতে পারে, এমনকি আদিম-জাতীয় বস্তুগুলির জন্য (বিগইন্টিজার, ইত্যাদি) ...
প্রাকৃতিক অ্যারে / ধারক অ্যাকসেসর এবং সাবস্ক্রিপশন:
// C++ container accessors, more natural
value = myArray[25] ; // subscript operator
value = myVector[25] ; // subscript operator
value = myString[25] ; // subscript operator
value = myMap["25"] ; // subscript operator
myArray[25] = value ; // subscript operator
myVector[25] = value ; // subscript operator
myString[25] = value ; // subscript operator
myMap["25"] = value ; // subscript operator
// Java container accessors, each one has its special notation
value = myArray[25] ; // subscript operator
value = myVector.get(25) ; // method get
value = myString.charAt(25) ; // method charAt
value = myMap.get("25") ; // method get
myArray[25] = value ; // subscript operator
myVector.set(25, value) ; // method set
myMap.put("25", value) ; // method put
জাভাতে, আমরা দেখতে পাই যে প্রতিটি পাত্রে একই জিনিস করা হয় (কোনও সূচক বা শনাক্তকারীর মাধ্যমে এর সামগ্রীটি অ্যাক্সেস করতে পারি), আমাদের এটি করার একটি আলাদা উপায় আছে, যা বিভ্রান্তিকর।
সি ++ এ, প্রতিটি কন্টেইনার তার সামগ্রী অ্যাক্সেস করতে একইভাবে ব্যবহার করে, অপারেটর ওভারলোডিংয়ের জন্য ধন্যবাদ।
প্রাকৃতিক উন্নত প্রকারের হেরফের
Matrix
" জাভা ম্যাট্রিক্স অবজেক্ট " এবং " সি ++ ম্যাট্রিক্স অবজেক্ট " এর জন্য গুগলে পাওয়া প্রথম লিঙ্কগুলি ব্যবহার করে নীচের উদাহরণগুলিতে একটি অবজেক্ট ব্যবহার করা হয়েছে :
// C++ YMatrix matrix implementation on CodeProject
// http://www.codeproject.com/KB/architecture/ymatrix.aspx
// A, B, C, D, E, F are Matrix objects;
E = A * (B / 2) ;
E += (A - B) * (C + D) ;
F = E ; // deep copy of the matrix
// Java JAMA matrix implementation (seriously...)
// http://math.nist.gov/javanumerics/jama/doc/
// A, B, C, D, E, F are Matrix objects;
E = A.times(B.times(0.5)) ;
E.plusEquals(A.minus(B).times(C.plus(D))) ;
F = E.copy() ; // deep copy of the matrix
এবং এটি ম্যাট্রিক্সের মধ্যে সীমাবদ্ধ নয়। BigInteger
এবং BigDecimal
জাভার ক্লাস, একই বিভ্রান্তিকর ভারবোসিটি ভোগা যেহেতু সি তাদের সমতুল ++, হিসাবে বিল্ট-ইন ধরনের স্পষ্ট।
প্রাকৃতিক পুনরাবৃত্তিকারী:
// C++ Random Access iterators
++it ; // move to the next item
--it ; // move to the previous item
it += 5 ; // move to the next 5th item (random access)
value = *it ; // gets the value of the current item
*it = 3.1415 ; // sets the value 3.1415 to the current item
(*it).foo() ; // call method foo() of the current item
// Java ListIterator<E> "bi-directional" iterators
value = it.next() ; // move to the next item & return the value
value = it.previous() ; // move to the previous item & return the value
it.set(3.1415) ; // sets the value 3.1415 to the current item
প্রাকৃতিক ফান্টেক্টর:
// C++ Functors
myFunctorObject("Hello World", 42) ;
// Java Functors ???
myFunctorObject.execute("Hello World", 42) ;
পাঠ্য সংক্ষিপ্তকরণ:
// C++ stream handling (with the << operator)
stringStream << "Hello " << 25 << " World" ;
fileStream << "Hello " << 25 << " World" ;
outputStream << "Hello " << 25 << " World" ;
networkStream << "Hello " << 25 << " World" ;
anythingThatOverloadsShiftOperator << "Hello " << 25 << " World" ;
// Java concatenation
myStringBuffer.append("Hello ").append(25).append(" World") ;
ঠিক আছে, জাভাতে আপনি খুব ব্যবহার করতে পারেন MyString = "Hello " + 25 + " World" ;
... তবে, এক সেকেন্ড অপেক্ষা করুন: এটি অপারেটর ওভারলোডিং, তাই না? এটা কি প্রতারণা করছে না ???
:-D
জেনেরিক কোড?
একই জেনেরিক কোড সংশোধনকারী অপারেটসগুলি বিল্ট-ইন / আদিম (যা জাভাতে কোনও ইন্টারফেস নেই), স্ট্যান্ডার্ড অবজেক্টস (যার সঠিক ইন্টারফেস থাকতে পারে না) এবং ব্যবহারকারী-সংজ্ঞায়িত অবজেক্টের জন্য উভয়ই ব্যবহারযোগ্য।
উদাহরণস্বরূপ, স্বেচ্ছাচারী ধরণের দুটি মানের গড় মূল্য গণনা:
// C++ primitive/advanced types
template<typename T>
T getAverage(const T & p_lhs, const T & p_rhs)
{
return (p_lhs + p_rhs) / 2 ;
}
int intValue = getAverage(25, 42) ;
double doubleValue = getAverage(25.25, 42.42) ;
complex complexValue = getAverage(cA, cB) ; // cA, cB are complex
Matrix matrixValue = getAverage(mA, mB) ; // mA, mB are Matrix
// Java primitive/advanced types
// It won't really work in Java, even with generics. Sorry.
অপারেটর ওভারলোডিং নিয়ে আলোচনা করা
অপারেটর ওভারলোডিং ব্যবহার করে সি ++ কোড এবং জাভাতে একই কোডের মধ্যে এখন আমরা ন্যায্য তুলনা দেখেছি, এখন আমরা একটি ধারণা হিসাবে "অপারেটর ওভারলোডিং" নিয়ে আলোচনা করতে পারি।
কম্পিউটারের আগে থেকেই অপারেটর ওভারলোডিংয়ের অস্তিত্ব ছিল
বাহিরে এমনকি কম্পিউটার বিজ্ঞান, সেখানে অপারেটর ওভারলোডিং হল: উদাহরণস্বরূপ, গণিত, অপারেটর পছন্দ +
, -
, *
, ইত্যাদি ওভারলোড করা হয়।
বস্তুত, এর গুরূত্ব +
, -
, *
, ইত্যাদি পরিবর্তন operands ধরনের (numerics, ভেক্টর, কোয়ান্টাম ওয়েভ ফাংশন, ম্যাট্রিক্স, ইত্যাদি) উপর নির্ভর করে।
আমাদের বেশিরভাগ, আমাদের বিজ্ঞান কোর্সের অংশ হিসাবে অপারেটরগুলির ধরণের উপর নির্ভর করে অপারেটরগুলির জন্য একাধিক তাৎপর্য শিখেছি। আমরা কি তাদের বিভ্রান্তিকর পেয়েছি?
অপারেটর ওভারলোডিং এর অপারেশনগুলির উপর নির্ভর করে
এটি অপারেটর ওভারলোডিংয়ের সর্বাধিক গুরুত্বপূর্ণ অংশ: গণিতে বা পদার্থবিদ্যার মতো, অপারেশনটি তার অপারেন্ডগুলির ধরণের উপর নির্ভর করে।
সুতরাং, অপারেন্ডের ধরণটি জানুন এবং আপনি অপারেশনের প্রভাব জানতে পারবেন।
এমনকি সি এবং জাভাতে (হার্ড-কোডেড) অপারেটর ওভারলোডিং রয়েছে
সি-তে, কোনও অপারেটরের আসল আচরণটি তার অপারেন্ডগুলি অনুযায়ী পরিবর্তন হবে। উদাহরণস্বরূপ, দুটি পূর্ণসংখ্যা যোগ করা দুটি ডাবল, বা একটি পূর্ণসংখ্যা এবং একটি দ্বিগুণ যোগ করার চেয়ে পৃথক। এমনকি পুরো পয়েন্টার গাণিতিক ডোমেন (কাস্টিং ব্যতীত, আপনি একটি পয়েন্টারে একটি পূর্ণসংখ্যার যোগ করতে পারেন, তবে আপনি দুটি পয়েন্টার যুক্ত করতে পারবেন না ...)।
জাভাতে, কোনও পয়েন্টার পাটিগণিত নেই, তবে +
অপারেটর ব্যতীত কেউ স্ট্রিং কনটেনটেশন খুঁজে পেয়েছেন যে "অপারেটর ওভারলোডিং ইজ ইজ ইজ ইজ" ক্রিয়ায় একটি ব্যতিক্রমকে ন্যায়সঙ্গত করতে যথেষ্ট হাস্যকর হবে।
এটি কেবলমাত্র আপনি সি (historicalতিহাসিক কারণে) বা জাভা ( ব্যক্তিগত কারণে , নীচে দেখুন) কোডার হিসাবে, আপনি নিজের নিজস্ব সরবরাহ করতে পারবেন না।
সি ++ এ অপারেটর ওভারলোডিং alচ্ছিক নয় ...
সি ++ এ, অন্তর্নির্মিত ধরণের জন্য অপারেটর ওভারলোডিং সম্ভব নয় (এবং এটি একটি ভাল জিনিস) তবে ব্যবহারকারী-সংজ্ঞায়িত প্রকারের ব্যবহারকারী-সংজ্ঞায়িত অপারেটর ওভারলোড থাকতে পারে।
যেমন ইতিমধ্যে আগেই বলা হয়েছে, সি ++ তে এবং জাভার বিপরীতে, ব্যবহারকারী-প্রকারগুলি অন্তর্নির্মিত প্রকারের তুলনায় ভাষার দ্বিতীয় শ্রেণির নাগরিক হিসাবে বিবেচিত হয় না। সুতরাং, যদি অন্তর্নির্মিত ধরণের অপারেটর থাকে তবে ব্যবহারকারী প্রকারগুলিতে সেগুলিও সক্ষম হওয়া উচিত।
সত্য যে, ভালো toString()
, clone()
, equals()
পদ্ধতি জাভা জন্য প্রযোজ্য ( অর্থাত আপাতদৃষ্টিতে-মানক মত ), সি ++ অপারেটর ওভারলোডিং C- এর এত অংশ ++, যে এটা উল্লেখ জাভা পদ্ধতি সামনে মূল সি অপারেটার প্রাকৃতিক, অথবা হয়ে ওঠে।
টেমপ্লেট প্রোগ্রামিংয়ের সাথে মিলিত হয়ে অপারেটর ওভারলোডিং একটি সুপরিচিত ডিজাইনের প্যাটার্নে পরিণত হয়। আসলে, আপনি নিজের ক্লাসের জন্য অতিরিক্ত লোড অপারেটর এবং ওভারলোডিং অপারেটরগুলি ব্যবহার না করে এসটিএলে খুব বেশি দূর যেতে পারবেন না।
... তবে এটি ব্যবহার করা উচিত নয়
অপারেটরের ওভারলোডিং অপারেটরের শব্দার্থকে সম্মান করার জন্য প্রচেষ্টা করা উচিত। কোনও +
অপারেটরে বিয়োগ করবেন না (যেমন "কোনও add
ফাংশনে বিয়োগ করবেন না ", বা "কোনও clone
পদ্ধতিতে ক্র্যাপ ফিরুন ")
কাস্ট ওভারলোডিং খুব বিপজ্জনক হতে পারে কারণ তারা অস্পষ্টতার দিকে নিয়ে যেতে পারে। সুতরাং সেগুলি সত্যই সংজ্ঞায়িত কেসগুলির জন্য সংরক্ষণ করা উচিত। &&
এবং হিসাবে ||
, আপনি কী করছেন তা যদি না আপনি সত্যিই জানেন না তবে এগুলি কখনই ওভারলোড করবেন না, যেহেতু আপনি সংক্ষিপ্ত সার্কিট মূল্যায়ন হারিয়ে ফেলবেন যা নেটিভ অপারেটররা উপভোগ করবেন &&
এবং ||
উপভোগ করবেন।
তো ... ঠিক আছে ... তাহলে জাভাতে কেন এটি সম্ভব নয়?
কারণ জেমস গোসলিং তাই বলেছেন:
আমি মোটামুটি ব্যক্তিগত পছন্দ হিসাবে অপারেটরকে ওভারলোডিং ছেড়ে দিয়েছি কারণ আমি অনেক লোককে C ++ এ অপব্যবহার করতে দেখেছি।
জেমস গোসলিং। সূত্র: http://www.gotw.ca/publications/c_family_interview.htm
উপরের গোসলিংয়ের পাঠ্যটি নীচের স্ট্রস্ট্রপের সাথে তুলনা করুন:
অনেকগুলি সি ++ ডিজাইনের সিদ্ধান্তগুলি আমার কিছু অপছন্দ করে কিছু নির্দিষ্ট উপায়ে করতে বাধ্য করার জন্য আমার অপছন্দের মূলগুলি [...] প্রায়শই আমি ব্যক্তিগতভাবে অপছন্দ করা এমন একটি বৈশিষ্ট্যকে নিষিদ্ধ করার প্রলোভন দেখায়, আমি তা করা থেকে বিরত থাকি কারণ আমার মনে হয় না যে আমার কাছে অন্যের উপর আমার মতামত জোর করার অধিকার ।
বাজনে স্ট্রস্ট্রপ। উত্স: সি ++ এর ডিজাইন এবং বিবর্তন (1.3 সাধারণ পটভূমি)
অপারেটর ওভারলোডিং জাভা উপকার করবে?
কিছু বস্তু অপারেটর ওভারলোডিং (কংক্রিট বা সংখ্যাযুক্ত ধরণের, যেমন বিগডিসিমাল, জটিল সংখ্যা, ম্যাট্রিকস, পাত্রে, পুনরাবৃত্তকারী, তুলনাকারী, পার্সার ইত্যাদি) থেকে প্রচুর উপকার পাবেন।
সি ++ এ আপনি স্ট্রাস্ট্রাপের বিনয়ের কারণে এই সুবিধাটি থেকে লাভ করতে পারেন। জাভাতে, আপনি গোসলিংয়ের ব্যক্তিগত পছন্দের কারণে খুব খারাপ হয়ে গেছেন ।
এটি জাভা যোগ করা যাবে?
জাভাতে এখন অপারেটর ওভারলোডিং যুক্ত না করার কারণগুলি অভ্যন্তরীণ রাজনীতির মিশ্রণ, বৈশিষ্ট্যটির অ্যালার্জি, বিকাশকারীদের অবিশ্বাস (আপনি জানেন, জাবা দলগুলিকে ঘৃণ্য মনে হয় এমন সাবোট্যুররা ...), আগের জেভিএমগুলির সাথে সামঞ্জস্যতা, একটি সঠিক স্পেসিফিকেশন, ইত্যাদি লেখার সময়
সুতরাং এই বৈশিষ্ট্যের জন্য অপেক্ষা করে শ্বাস ধরে রাখবেন না ...
তবে তারা এটি সি # তে করে !!!
হ্যাঁ ...
যদিও এটি দুটি ভাষার মধ্যে একমাত্র পার্থক্য থেকে দূরে, এইটি কখনও আমাকে আনন্দ করতে ব্যর্থ হয়।
স্পষ্টতই, সি # জনগণ তাদের "প্রতিটি আদিম একটি struct
, এবং struct
অবজেক্ট থেকে প্রাপ্ত" দিয়ে প্রথম চেষ্টা করে ঠিকই পেয়েছিলেন।
ব্যবহৃত সংজ্ঞায়িত অপারেটর ওভারলোডিংয়ের বিরুদ্ধে সমস্ত FUD সত্ত্বেও, নিম্নোক্ত ভাষাগুলি এটি সমর্থন করে: স্কালা , ডার্ট , পাইথন , এফ # , সি # , ডি , আলগোল 68 , স্মলটালক , গ্রোভি , পারল 6 , সি ++, রুবি , হাস্কেল , ম্যাটল্যাব , আইফেল , লুয়া , ক্লোজার , ফোর্টরান 90 , সুইফ্ট , অ্যাডা , ডেলফি 2005 ...
এতগুলি ভিন্ন ভিন্ন (এবং কখনও কখনও বিরোধী) দর্শন সহ অনেকগুলি ভাষা, এবং তবুও তারা সকলেই এই বিষয়ে একমত হয়।
চিন্তার জন্য খাদ্য...