অপারেটর ওভারলোডিং এর উদাহরণ, যা বোঝায় [বন্ধ]


12

আমি সি # শিখার সময়, আমি এটি দেখতে পেয়েছি, সি # অপারেটর ওভারলোডিং সমর্থন করে। আমার ভাল উদাহরণ সহ সমস্যা আছে যা:

  1. জ্ঞান তৈরি করুন (উদাঃ ভেড়া এবং গরু নামে শ্রেণি যুক্ত)
  2. দুটি স্ট্রিং সংমিশ্রনের উদাহরণ নয়

বেস ক্লাস লাইব্রেরি থেকে উদাহরণ স্বাগত।


10
'জ্ঞান' সংজ্ঞায়িত করুন, দয়া করে! সিরিয়াসলি, এই বিষয়টিকে নিয়ে তিক্ত এবং মমত্বাহীন বিতর্কগুলি বোঝায় যে এটি সম্পর্কে সঠিকভাবে বিশাল মতবিরোধ রয়েছে। অনেক কর্তৃপক্ষ ওভারলোডেড অপারেটরদের প্রত্যাখ্যান করে কারণ তাদেরকে একেবারে অপ্রত্যাশিত কাজ করা যেতে পারে। অন্যরা উত্তর দেয় যে পদ্ধতির নামগুলিও একইভাবে সম্পূর্ণ অপ্রচলিত হিসাবে বেছে নেওয়া যেতে পারে, তবে নামযুক্ত কোড ব্লকগুলি প্রত্যাখ্যান করার কোনও কারণ নেই! আপনি সম্ভবত অবশ্যই এমন কোনও উদাহরণ পেতে যাচ্ছেন না যা সাধারণত বোধগম্য বলে বিবেচিত হয়। আপনার কাছে বোধগম্য উদাহরণগুলি - সম্ভবত।
কিলিয়ান ফট

@ কিলিয়ানফথের সাথে সম্পূর্ণ সম্মত হন agree শেষ পর্যন্ত যে প্রোগ্রামটি সংকলন করে তা সংকলক করে তোলে। তবে ==গুণ বেশি করার জন্য যদি ওভারলোড হয় তবে তা আমার কাছে বোধগম্য তবে অন্যের কাছে তা বোধগম্য নয় ! এই প্রশ্নটি কোন প্রোগ্রামিং ল্যাঙ্গুয়েজের বৈধতা সম্পর্কে বা আমরা 'সেরা অনুশীলনের কোডিং' সম্পর্কে কথা বলছি?
দিপান মেহতা

উত্তর:


27

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

সামান্য বেশি abstractly, অপারেটর যখন করণ ব্যবহৃত করা যেতে পারে মত সেট অপারেশন, তাই operator+একটি হতে পারে ইউনিয়ন , operator-হতে পারে একটি সম্পূরক , ইত্যাদি এই দৃষ্টান্ত যদিও প্রসারিত করতে শুরু হবে বিশেষ করে যদি আপনি সংযোজন বা একটি অপারেশন যা আইএসএন 'এর জন্য গুণ অপারেটর ব্যবহার টি পরিবর্তিত হবে না , যেমনটি আপনি আশা করতে পারেন।

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

পিউরিস্টের জন্য, স্ট্রিং +অপারেটরের সমস্যাগুলির মধ্যে একটি হ'ল এটি চলমান নয়। "a"+"b"হিসাবে একই হয় না "b"+"a"। স্ট্রিংগুলির জন্য আমরা এই ব্যতিক্রমটি বুঝতে পারি কারণ এটি এতটা সাধারণ, তবে আমরা কীভাবে বলতে পারি যে operator+অন্য ধরণের ক্ষেত্রে ব্যবহার করা চলবে কিনা? বেশিরভাগ লোকেরা ধরে নেবে যে এটি হ'ল যদি না অবজেক্টটি স্ট্রিং-জাতীয় না হয় তবে আপনি কখনই সত্যই জানেন না যে লোকেরা কী ধারণা করবে।

স্ট্রিংয়ের মতো ম্যাট্রিকের ফাউবিলগুলিও বেশ সুপরিচিত। এটা সুস্পষ্ট যে Matrix operator* (double, Matrix)এটি একটি স্কেলারের গুণ, যেখানে উদাহরণস্বরূপ Matrix operator* (Matrix, Matrix)একটি ম্যাট্রিক্স গুণ (যেমন ডট-প্রোডাক্ট গুণের একটি ম্যাট্রিক্স) হবে।

একইভাবে প্রতিনিধিদের সাথে অপারেটরদের ব্যবহার গণিত থেকে এতটা স্পষ্টভাবে মুছে ফেলা হয়েছে যে আপনি এই ভুলগুলি করার সম্ভাবনা পাচ্ছেন না।

উল্লেখ্য, এ 2011 ACCU সম্মেলনে , রজার Orr & স্টিভ ভালবাসা একটি সেশন উপস্থাপন সমতা, মান এবং পরিচয় অনেক অর্থ কটাক্ষপাত - কিছু বস্তু অন্যদের তুলনায় বেশি সমান । তাদের স্লাইডগুলি ডাউনলোডযোগ্য , যেমন ভাসমান পয়েন্ট সমতা সম্পর্কে রিচার্ড হ্যারিসের পরিশিষ্ট । সারাংশ: খুব সতর্কতা অবলম্বন করা আবশ্যক সঙ্গে operator==, এখানে ড্রাগন হতে!

অপারেটর ওভারলোডিং একটি অত্যন্ত শক্তিশালী শব্দার্থক কৌশল, তবে এটি অতিরিক্ত ব্যবহার করা সহজ। আদর্শভাবে আপনার কেবলমাত্র এমন পরিস্থিতিতে ব্যবহার করা উচিত যখন ওভারলোডেড অপারেটরের প্রভাব কী তা প্রসঙ্গ থেকে খুব স্পষ্ট হয়। অনেক উপায়ে a.union(b)চেয়ে পরিষ্কার হয় a+b, এবং a*bহয় অনেক চেয়ে বেশি অস্পষ্ট a.cartesianProduct(b), বিশেষ করে থেকে কার্টিজিয়ান পণ্য এর ফলে হবে SetLike<Tuple<T,T>>একটি বদলে SetLike<T>

অপারেটর ওভারলোডিংয়ের সাথে আসল সমস্যাগুলি তখন আসে যখন কোনও প্রোগ্রামার ধরে নেয় যে কোনও শ্রেণি একটি উপায়ে আচরণ করবে তবে এটি আসলে অন্যরকম আচরণ করে। এই ধরণের অর্থপূর্ণ সংঘর্ষটি আমি এড়াতে চেষ্টা করা জরুরী পরামর্শ দিচ্ছি।


1
আপনি বলছেন যে ম্যাট্রিক্সের অপারেটররা মানচিত্রের মানচিত্রটি সত্যিই ভাল, তবে ম্যাট্রিক্সের গুণটি কমিটিকেটিভ নয়। এছাড়াও প্রতিনিধিদের অপারেটররা আরও শক্তিশালী। আপনি d1 + d2একই ধরণের যে কোনও দুটি প্রতিনিধিকে করতে পারেন ।
সুইভ

1
@ মার্ক: "ডট পণ্য" কেবলমাত্র ভেক্টরগুলিতে সংজ্ঞায়িত করা হয়; দুটি ম্যাট্রিককে গুণিত করার জন্য কেবল "ম্যাট্রিক্স গুণন" বলা হয়। পার্থক্যটি কেবল শব্দার্থকতার চেয়ে বেশি: ডট পণ্য একটি স্কেলার ফিরিয়ে দেয়, যখন ম্যাট্রিক্স-গুণটি একটি ম্যাট্রিক্স দেয় (এবং এটি উপায় দ্বারা, বহির্গামী নয়)
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট

26

আমি অবাক হয়েছি কেউই ছাত্রলীগের আরও আকর্ষণীয় মামলার উল্লেখ করেনি: DateTimeএবং TimeSpan। আপনি পারেন:

  • TimeSpanঅন্যটি পেতে দুটি গুলি যোগ করুন বা বিয়োগ করুনTimeSpan
  • একটি উপর ইউনারী বিয়োগ ব্যবহার TimeSpanএকটি অস্বীকার পেতেTimeSpan
  • DateTimeএকটি পেতে দুটি গুলি বিয়োগTimeSpan
  • অন্যটি পেতে TimeSpanএকটি থেকে বিয়োগ বা বিয়োগ করুনDateTimeDateTime

অপারেটার যে ধরনের অনেক উপর ইন্দ্রিয় বানাতে পারে আরেকটি সেট <, >, <=, >=। ছাত্রলীগে উদাহরণস্বরূপ Versionএগুলি প্রয়োগ করে।


পেডেন্টিক তত্ত্বগুলির চেয়ে খুব বাস্তব উদাহরণ!
এসআইস্লাম

7

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

এছাড়াও, যেহেতু আমি জাভাও করি এবং জাভা ওভারলোডিং অপারেটরদের অনুমতি দেয় না, এটি অবিশ্বাস্যভাবে মিষ্টি লিখতে দেয়

BigInteger bi = new BigInteger(0);
bi += 10;

থান, জাভা:

BigDecimal bd = new BigDecimal(0);
bd = bd.add(new BigDecimal(10));

5

আমি খুশী হয়ে আমি এটি দেখেছি কারণ আমি আয়রনির সাথে বোকা বানাচ্ছি এবং এতে অপারেটর ওভারলোডিংয়ের দুর্দান্ত ব্যবহার রয়েছে। এটি কী করতে পারে তার একটি নমুনা এখানে

সুতরাং লোহা একটি "। নেট ভাষা বাস্তবায়ন কিট" এবং একটি পার্সার জেনারেটর (একটি এলএলআর পার্সার তৈরি করে)। পার্সার জেনারেটর যেমন ইয়্যাক / লেক্সের মতো কোনও নতুন সিনট্যাক্স / ভাষা শিখার পরিবর্তে আপনি অপারেটরের ওভারলোড দিয়ে সি # তে ব্যাকরণটি লিখুন। এখানে একটি সরল বিএনএফ ব্যাকরণ

// BNF 
Expr := Term | BinExpr
Term := number | ParExpr
ParExpr := "(" + Expr + ")"
BinExpr := number + BinOp + number
BinOp := "+" | "-" | "*" | "/"
number := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

সুতরাং এটি একটি সহজ সামান্য ব্যাকরণ (যদি আমি কেবল বিএনএফ শিখি এবং ব্যাকরণ তৈরি করি তবে এখানে কোনও অসঙ্গতি থাকলে দয়া করে তাকে ক্ষমা করুন)। এখন সি # তে নজর দিন:

  var Expr = new NonTerminal("Expr");
  var Term = new NonTerminal("Term");
  var BinExpr = new NonTerminal("BinExpr");
  var ParExpr = new NonTerminal("ParExpr");
  var BinOp = new NonTerminal("BinOp");
  var Statement = new NonTerminal("Statement");
  var ProgramLine = new NonTerminal("ProgramLine");
  var Program = new NonTerminal("Program", typeof(StatementListNode));
  // BNF Rules - Overloading
  Expr.Rule = Term | BinExpr;
  Term.Rule = number | ParExpr;
  ParExpr.Rule = "(" + Expr + ")";
  BinExpr.Rule = Expr + BinOp + Expr;
  BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**";

আপনি দেখতে পাচ্ছেন, অপারেটরকে ওভারলোডিংয়ের সাথে, সি # তে ব্যাকরণটি লিখতে প্রায় ঠিক বিএনএফ-তে ব্যাকরণ লেখা হয়। আমার কাছে এটি কেবল বোধগম্য নয় তবে অপারেটর ওভারলোডিংয়ের দুর্দান্ত ব্যবহার।


3

মূল উদাহরণটি হ'ল অপারেটর == / অপারেটর! =।

আপনি যদি রেফারেন্সের পরিবর্তে ডেটা মান দ্বারা দুটি বস্তু সহজেই তুলনা করতে চান তবে আপনি ওভারলোড করতে চাইবেন quকুয়ালস (এবং। গেটহ্যাশকোড!), এবং অবিচ্ছিন্নতার জন্য! = এবং == অপারেটরগুলি করতেও চান।

আমি সি # তে অন্য অপারেটরগুলির কোনও বুনো ওভারলোড দেখিনি (যদিও আমি ধারণা করি এমন প্রান্তের কেস রয়েছে যেখানে এটি কার্যকর হতে পারে)।


1

এমএসডিএন-এর এই উদাহরণটি দেখায় যে কীভাবে জটিল সংখ্যাগুলি প্রয়োগ করা যায় এবং তাদেরকে সাধারণ + অপারেটর ব্যবহার করতে হয়।

আর একটি উদাহরণ ম্যাট্রিক্স সংযোজনের জন্য এটি কীভাবে করবেন তা দেখায় এবং গ্যারেজে গাড়ি যুক্ত করতে কীভাবে এটি ব্যবহার করবেন না তাও ব্যাখ্যা করে (লিঙ্কটি পড়ুন)।


0

ওভারলোডের ভাল ব্যবহার বিরল হতে পারে, তবে তা ঘটে।

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

আমি নির্দিষ্ট পরিস্থিতিতে কাস্টার অপারেটর ওভারলোডগুলি কাজ করতে উপযুক্ত বলে মনে করি। উদাহরণস্বরূপ, আমাকে এক্সএমএল-তে 0 বা 1 হিসাবে উপস্থাপন করা একটি বুলিয়ান সিরিয়ালাইজ / ডেসিরিয়ালাইজ করতে হয়েছিল ডান (অন্তর্নিহিত বা স্পষ্টতই, আমি ভুলে যাচ্ছি) কুল অপারেটরটি বুলিয়ান থেকে ইনট এবং পিছনে কৌশলটি করেছিলেন।


4
এটি ঠিকানাগুলির তুলনা করতে বাধা দেয় না: আপনি এখনও ব্যবহার করতে পারেন object.ReferenceEquals()
dan04

@ dan04 জানতে পেরে খুব ভাল!
এমপিলেটিয়ার

ঠিকানাগুলির তুলনা করার আরেকটি উপায় হ'ল ingালাইয়ের মাধ্যমে অবজেক্টের ব্যবহারকে জোর করা ==: (object)foo == (object)barসর্বদা রেফারেন্সগুলির সাথে তুলনা করা। তবে আমি পছন্দ করব ReferenceEquals(), যেমন @ ডান04 উল্লেখ করেছে কারণ এটি কী করে তা স্পষ্ট।
সুইভ

0

এগুলি অপারেটর ওভারলোডিংয়ের বিষয়গুলির বিষয়ে লোকেরা সাধারণত ভাবেন এমন বিষয়শ্রেণীতে নয়, তবে আমি মনে করি যে ওভারলোডে সক্ষম হওয়া সবচেয়ে গুরুত্বপূর্ণ অপারেটরগুলির মধ্যে একটি হ'ল রূপান্তর অপারেটর

রূপান্তর অপারেটরগুলি বিশেষত মানের ধরণের জন্য দরকারী যা একটি সংখ্যার ধরণের "ডি-চিনি" করতে পারে বা কিছু প্রসঙ্গে সংখ্যার প্রকারের মতো কাজ করতে পারে। উদাহরণস্বরূপ, যদি আপনি একটি বিশেষ সংজ্ঞায়িত পারে Idযে ধরনের একটি নির্দিষ্ট শনাক্তকারী প্রতিনিধিত্ব করে আর আপনি একটি প্রদান করতে পারে অন্তর্নিহিত রূপান্তর intযাতে আপনি একটি পাস করতে পারেন Idএকটি পদ্ধতি যে একটি লাগে int, কিন্তু একটি explict থেকে রুপান্তরের intজন্য Idযাতে কেউ একটি পাস করতে পারেন intএকটি মধ্যে পদ্ধতিটি Idএটি প্রথমে ing ালাই ছাড়াই নেয় ।

সি # এর বাইরের উদাহরণ হিসাবে পাইথন ভাষায় অনেকগুলি বিশেষ ব্যবহার রয়েছে যা ওভারলোডযোগ্য অপারেটর হিসাবে প্রয়োগ করা হয়। এর মধ্যে inসদস্যপদ পরীক্ষার জন্য অপারেটর, ()কোনও বিষয়টিকে কল করার lenজন্য অপারেটর এবং এটি কোনও অবজেক্টের দৈর্ঘ্য বা আকার নির্ধারণের জন্য অন্তর্ভুক্ত রয়েছে।

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


0

পয়েন্ট Struct মধ্যে System.Drawing নামস্থান দুটি ভিন্ন অপারেটর ওভারলোডিং অবস্থানগুলি তুলনা করতে ওভারলোডিং ব্যবহার করে।

 Point locationA = new Point( 50, 50 );
 Point locationB = new Point( 50, 50 );

 if ( locationA == locationB )
    Console.WriteLine( "Their locations are the same" );
 else
    Console.WriteLine( "Their locations  are different" );

আপনি দেখতে পাচ্ছেন, ওভারলোড ব্যবহার করে দুটি অবস্থানের এক্স এবং ওয়াই কো-অর্ডিনেটের তুলনা করা অনেক সহজ।


0

আপনি যদি গাণিতিক ভেক্টরের সাথে পরিচিত হন তবে আপনি +অপারেটরকে ওভারলোডিংয়ে ব্যবহার দেখতে পাবেন see আপনি একটি ভেক্টর যোগ করতে পারিনি a=[1,3]সঙ্গে b=[2,-1]এবং পেতে c=[3,2]

সমতুল্য ওভারলোডিং (==) এছাড়াও দরকারী হতে পারে (যদিও এটি কোনও equals()পদ্ধতি বাস্তবায়ন করা আরও ভাল )। ভেক্টরের উদাহরণগুলি চালিয়ে যেতে:

v1=[1,3]
v2=[1,3]
v1==v2 // True

-2

কোনও ফর্মের জন্য অঙ্কনের জন্য কোডের একটি অংশের কল্পনা করুন

{
  Point p = textBox1.Location;
  Size dp = textBox1.Size;

  // Here the + operator has been overloaded by the CLR
  p += dp;  // Now p points to the lower right corner of the textbox.
  ..
}

আরেকটি সাধারণ উদাহরণ হ'ল যখন কোনও কাঠামো ভেক্টরের আকারে অবস্থানের তথ্য ধরে রাখতে ব্যবহৃত হয়।

public struct Pos
{
    public double x, y, z;
    public double Distance { get { return Math.Sqrt(x * x + y * y + z * z); } }
    public static Pos operator +(Pos A, Pos B)
    {
        return new Pos() { x = A.x + B.x, y = A.y + B.y, z = A.z + B.z };
    }
    public static Pos operator -(Pos A, Pos B)
    {
        return new Pos() { x = A.x - B.x, y = A.y - B.y, z = A.z - B.z };
    }
}

শুধুমাত্র পরে হিসাবে ব্যবহার করা

{
    Pos A = new Pos() { x = 4, y = -1, z = 0.5 };
    Pos B = new Pos() { x = 8, y = 2, z = 1.5 };

    double x = (B - A).Distance;
}

4
আপনি ভেক্টর যুক্ত করুন, অবস্থানগুলি নয়: কখন ওভারলোড করা operator+উচিত নয় (এটি একটি ভেক্টরের শর্তে আপনি একটি পয়েন্ট প্রয়োগ করতে পারেন, তবে আপনি দুটি পয়েন্ট যোগ করতে সক্ষম হবেন না) এর
ব্লুরাজা - ড্যানি পিফ্লুঘুফ্ট

@ BlueRaja-DannyPflughoeft: যোগ করার পদ্ধতি অন্য অবস্থানে অর্থে দেখা যায় না উত্পাদ অবস্থানের, কিন্তু তাদের বিয়োগ (ক ভেক্টর উত্পাদ করার জন্য) আছে, যেমন নেই গড় তাদের। কেউ পি 1, পি 2, পি 3 এবং পি 4 এর মাধ্যমে গড় গণনা করতে পারে p1+((p2-p1)+(p3-p1)+(p4-p1))/4তবে এটি কিছুটা বিশ্রী বলে মনে হয়।
সুপারক্যাট

1
অ্যাফাইন জ্যামিতিতে আপনি পয়েন্ট এবং রেখার সাথে বীজগণিত করতে পারেন যেমন সংযোজন, স্কেলিং ইত্যাদি বাস্তবায়নের জন্য যদিও একজাতীয় স্থানাঙ্কের প্রয়োজন হয়, যা সাধারণত 3 ডি গ্রাফিক্সে ব্যবহৃত হয়। দুটি পয়েন্ট সংযোজন আসলে তাদের গড়ের ফলাফল।
ja72
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.