সি ++ এর সমস্ত কিছুর জন্য বস্তুগুলি (আদিম ধরণের পরিবর্তে) ব্যবহার করা কি বোধগম্য হবে?


17

একটি সাম্প্রতিক প্রকল্পের সময় আমি কাজ করছি, আমাকে এরকম দেখতে বেশ কয়েকটি ফাংশন ব্যবহার করতে হয়েছিল:

static bool getGPS(double plane_latitude, double plane_longitude, double plane_altitude,
                       double plane_roll, double plane_pitch, double plane_heading,
                       double gimbal_roll, double gimbal_pitch, double gimbal_yaw, 
                       int target_x, int target_y, double zoom,
                       int image_width_pixels, int image_height_pixels,
                       double & Target_Latitude, double & Target_Longitude, double & Target_Height);

সুতরাং আমি এটির মতো দেখতে কিছুটা দেখতে চাই:

static GPSCoordinate getGPS(GPSCoordinate plane, Angle3D planeAngle, Angle3D gimbalAngle,
                            PixelCoordinate target, ZoomLevel zoom, PixelSize imageSize)

এটি আমার কাছে প্রথম পদ্ধতির চেয়ে উল্লেখযোগ্যভাবে বেশি পঠনযোগ্য এবং নিরাপদ বলে মনে হয়। কিন্তু এটা তৈরি করতে জানার জন্য PixelCoordinateএবং PixelSizeশ্রেণীর? অথবা আমি কেবল std::pair<int,int>প্রত্যেকটির জন্য ব্যবহার করা ভাল । এবং এটি একটি ZoomLevelবর্গ আছে বোঝা যায় না , বা আমি শুধু একটি ব্যবহার করা উচিত double?

প্রতিটি কিছুর জন্য ক্লাস ব্যবহার করার পিছনে আমার স্বজ্ঞাততা এই অনুমানগুলির উপর ভিত্তি করে:

  1. যদি প্রতিটি কিছুর জন্য ক্লাস থাকে তবে ZoomLevelযেখানে কোনও Weightবস্তুর প্রত্যাশা ছিল সেখানে পাস করা অসম্ভব , সুতরাং কোনও ফাংশনে ভুল যুক্তি সরবরাহ করা আরও কঠিন হবে
  2. তেমনি কিছু অবৈধ ক্রিয়াকলাপ সংকলনের ত্রুটিগুলির কারণ হতে পারে যেমন GPSCoordinateএকটি ZoomLevelবা অন্যটিতে যুক্ত করাGPSCoordinate
  3. আইনী ক্রিয়াকলাপগুলি প্রতিনিধিত্ব করা এবং টাইপসেফের পক্ষে সহজ হবে। অর্থাত্ দুটি GPSCoordinateগুলি বিয়োগ করলে ফলন হয়GPSDisplacement

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


8
"বেশিরভাগ সি ++ কোড আমি দেখেছি প্রচুর আদিম ধরণের ব্যবহার করে" - দুটি ধারণা মাথায় আসে: সি ++ এর কোড প্রচুর প্রোগ্রামারদের দ্বারা লিখিত হতে পারে যার দুর্বল বিমূর্ততা রয়েছে; এছাড়াও স্টার্জন আইন
কংগ্রেসবঙ্গাস

3
এবং আমি মনে করি এটি আদিম প্রকারগুলি সহজ, সোজা, দ্রুত, মসৃণ এবং দক্ষ because এখন ওপির উদাহরণে, কিছু নতুন ক্লাস চালু করা অবশ্যই একটি ভাল ধারণা। তবে শিরোনাম প্রশ্নের উত্তর (যেখানে এটি "সবকিছু" বলছে) একটি দুর্দান্ত সংখ্যার!
মিস্টার লিস্টার

1
@ ম্যাক্স টাইপডেফিং ডাবলস ওপির সমস্যা সমাধানে একেবারে কিছুই করে না।
মিস্টার লিস্টার

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

1
এই উক্তিটি যেমন চলেছে "যদি আপনার 17 টি পরামিতি সহ কোনও ফাংশন থাকে তবে আপনি সম্ভবত কয়েকটি মিস করেছেন"।
জোরিস টিমারম্যানস 15

উত্তর:


24

হ্যাঁ, অবশ্যই। যে সমস্ত কার্য / পদ্ধতিগুলি অনেক বেশি আর্গুমেন্ট গ্রহণ করে তা হ'ল একটি কোড গন্ধ , এবং নিম্নলিখিতগুলির মধ্যে কমপক্ষে একটি নির্দেশ করে:

  1. ফাংশন / পদ্ধতি একবারে অনেকগুলি কাজ করে
  2. ফাংশন / পদ্ধতিতে অনেকগুলি অ্যাক্সেস প্রয়োজন কারণ এটি জিজ্ঞাসা করছে না, কিছু ওও ডিজাইন আইন লঙ্ঘন করছে না বা লঙ্ঘন করছে না
  3. যুক্তিগুলি আসলে নিবিড়ভাবে সম্পর্কিত

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

static GPSCoordinate getGPS(Plane plane, Angle3D gimbalAngle, GPSView view)

(আমি জিপিএসের সাথে পরিচিত নই তাই এটি সম্ভবত সঠিক বিমূর্ততা নয়; উদাহরণস্বরূপ, জুম নামে একটি ফাংশনটি কী করতে হবে তা আমি বুঝতে পারি না getGPS))

দুজনের একই ডেটা থাকলেও দয়া করে PixelCoordinateওভারের মতো ক্লাস পছন্দ std::pair<T, T>করুন। এটি শব্দার্থক মান যোগ করে, অতিরিক্ত কিছু ধরণের সুরক্ষা যোগ করে (সংকলক উভয়ই সত্ত্বেও ScreenCoordinateআপনাকে পাস করতে বাধা দেবে ।PixelCoordinatepair


1
উল্লেখ করার দরকার নেই যে ছোট্ট কিছু মাইক্রো-অপ্টিমাইজেশনের জন্য আপনি শীতল বাচ্চারা চেষ্টা করছেন তবে সত্যই করা উচিত নয়
রেচেট ফ্রিক

6

দাবি অস্বীকার: আমি সি ++ এর চেয়ে সি পছন্দ করি

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

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

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

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

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

তেমনি কিছু অবৈধ ক্রিয়াকলাপ সংকলন ত্রুটির কারণ হতে পারে, যেমন একটি জুমলেভেল বা অন্য কোনও জিপিএসকর্ডিনেটে জিপিএসকর্ডিনেট যুক্ত করা

অপারেটর ওভারলোডগুলির ভাল ব্যবহার।

আইনী ক্রিয়াকলাপগুলি প্রতিনিধিত্ব করা এবং টাইপসেফের পক্ষে সহজ হবে। অর্থাত্ দুটি GPSCoordinates বিয়োগ করলে একটি GPSDisplacement পাওয়া যায়

অপারেটর ওভারলোডগুলিরও ভাল ব্যবহার।

আমি মনে করি আপনি সঠিক পথে আছেন আরেকটি বিষয় বিবেচনা করার বিষয় হ'ল এটি কীভাবে প্রোগ্রামের বাকী অংশগুলির সাথে খাপ খায়।


3

ডেডিকেটেড প্রকারগুলি ব্যবহার করে সুবিধা রয়েছে যে আর্গুমেন্টের ক্রমটি আঁকতে এটি আরও শক্ত। আপনার উদাহরণ ফাংশনের প্রথম সংস্করণ, উদাহরণস্বরূপ, 9 ডাবলসের শৃঙ্খলা দিয়ে শুরু হয়। যখন কেউ এই ফাংশনটি ব্যবহার করেন, তখন জিপিএস স্থানাঙ্কের স্থলে এবং তদ্বিপরীতভাবে ক্রমটি ক্রম করা এবং গিম্বল কোণগুলি পাস করা খুব সহজ। এটি খুব অদ্ভুত এবং বাগগুলি সনাক্ত করতে শক্ত হতে পারে। পরিবর্তে আপনি যখন বিভিন্ন ধরণের সাথে কেবল তিনটি আর্গুমেন্ট পাস করেন তখন এই ত্রুটিটি সংকলক দ্বারা ধরা যেতে পারে।

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

আমি টাইপডেফগুলি ব্যবহার করার পরামর্শ দেব যা কেবলমাত্র প্রকারভেদ ( typedef double ZoomLevel) জন্য কেবলমাত্র কারণ হিসাবে নয়, অন্যটির জন্যও একটি পৃথক নাম: এটি সহজেই আপনাকে পরে টাইপটি পরিবর্তন করতে দেয়। আপনি যখন একদিন ধারণা পান যে ব্যবহার floatকরা ঠিক তত ভাল doubleহতে পারে তবে এটি আরও মেমরি হতে পারে- এবং সিপিইউ-দক্ষ, আপনার কেবল এটি এক জায়গায় পরিবর্তন করতে হবে, ডোজেন্সে নয়।


টাইপিডেফ পরামর্শের জন্য +1। আপনাকে উভয় জগতের সেরা দেয়: আদিম ধরণের এবং বস্তু।
কার্ল বিলেফেল্ট

কোনও টাইপয়েফের চেয়ে শ্রেণীর সদস্যের ধরণ পরিবর্তন করা আর কঠিন নয়; বা আপনি কি আদিমদের সাথে তুলনা করেছেন?
মাহুজা

2

এখানে ইতিমধ্যে সুন্দর উত্তর, তবে একটি জিনিস আমি যুক্ত করতে চাই:

ব্যবহার PixelCoordinateএবং PixelSizeশ্রেণি জিনিসগুলিকে খুব নির্দিষ্ট করে তোলে। একটি সাধারণ Coordinateবা Point2Dশ্রেণি সম্ভবত আপনার প্রয়োজনের সাথে আরও ভাল মানায়। এ Point2Dসর্বাধিক সাধারণ পয়েন্ট / ভেক্টর ক্রিয়াকলাপ বাস্তবায়ন করে এমন একটি শ্রেণী হওয়া উচিত। আপনি যেমন শ্রেণিটি এমনকি উদারভাবে প্রয়োগ Point2D<T>করতে পারেন ( যেখানে টি হতে পারে intবা doubleঅন্য কিছু হতে পারে )।

2D পয়েন্ট / ভেক্টর অপারেশন প্রচুর 2D জ্যামিতি প্রোগ্রামিং কাজের জন্য খুব সাধারণ যে আমার অভিজ্ঞতার সাথে এই জাতীয় সিদ্ধান্তটি 2D অপারেশনগুলিকে পুনরায় ব্যবহারের সম্ভাবনা বাড়িয়ে তুলবে। আপনি প্রতিটি জন্য তাদের পুনরায় বাস্তবায়ন প্রয়োজনীয়তার এড়াতে হবে PixelCoordinate, GPSCoordinate, "Whatsover" -Coordinate বর্গ আবার এবং আবার।


1
আপনি struct PixelCoordinate:Point2D<int>যদি উপযুক্ত ধরণের সুরক্ষা চান তবে আপনি এটি করতেও পারেন
ratchet freak

0

সুতরাং আমি এটির মতো দেখতে কিছুটা দেখতে চাই:

static GPSCoordinate getGPS(GPSCoordinate plane, Angle3D planeAngle, Angle3D gimbalAngle,
                        PixelCoordinate target, ZoomLevel zoom, PixelSize imageSize)

এটি আমার কাছে প্রথম পদ্ধতির চেয়ে উল্লেখযোগ্যভাবে বেশি পঠনযোগ্য এবং নিরাপদ বলে মনে হয়।

এটি [আরও পাঠযোগ্য] এটি একটি ভাল ধারণা।

তবে পিক্সেলসর্ডিনেট এবং পিক্সেলসাইজ ক্লাস তৈরি করা কি বোধগম্য?

যদি তারা বিভিন্ন ধারণার প্রতিনিধিত্ব করে তবে এটি অর্থবোধ করে (এটি "হ্যাঁ।")।

অথবা আমি প্রত্যেকের জন্য কেবল স্টাডি :: জোড় ব্যবহার করা ভাল।

আপনি করে শুরু করতে পারেন typedef std::pair<int,int> PixelCoordinate, PixelSize;। এইভাবে, আপনি শব্দার্থবিজ্ঞানগুলি কভার করুন (আপনি পিক্সেল স্থানাঙ্ক এবং পিক্সেল আকারের সাথে কাজ করছেন, আপনার ক্লায়েন্ট কোডে স্টাড :: জোড়া দিয়ে নয়) এবং যদি আপনাকে প্রসারিত করার দরকার হয় তবে আপনি কেবল টাইপএফটি একটি শ্রেণীর সাথে প্রতিস্থাপন করুন এবং আপনার ক্লায়েন্ট কোডটি অবশ্যই নূন্যতম পরিবর্তন প্রয়োজন।

এবং জুমলিভেল ক্লাস করা কি বোধগম্য নয়, বা আমার কেবল একটি ডাবল ব্যবহার করা উচিত?

আপনি এটি টাইপও করতে পারেন, তবে আমি doubleএটির সাথে এটি ব্যবহার করব যতক্ষণ না এর সাথে ডাবলটির অস্তিত্ব না থাকার সাথে আমার কার্যকারিতা প্রয়োজন হয় (উদাহরণস্বরূপ, একটি ZoomLevel::defaultমান থাকার জন্য আপনার ক্লাস সংজ্ঞায়িত করা প্রয়োজন, তবে যতক্ষণ না আপনার মতো কিছু থাকে) যে, এটি একটি ডাবল রাখুন)।

প্রতিটি কিছুর জন্য ক্লাস ব্যবহার করার পিছনে আমার অনুভূতি এই অনুমানগুলির উপর ভিত্তি করে [ব্রেভিটির জন্য বাদ দেওয়া]

এগুলি দৃ strong় যুক্তি (আপনার ইন্টারফেসগুলি সঠিকভাবে ব্যবহার করা সহজ এবং ভুলভাবে ব্যবহার করা কঠিন করার চেষ্টা করা উচিত)।

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

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

কোনও কিছুর জন্য অবজেক্ট ব্যবহার করা কি ভাল ধারণা, বা এর কি ডাউনসাইড রয়েছে যা আমি অবগত নই?

আপনার মানগুলি সর্বদা একসাথে উপস্থিত হলে (এবং কোনও অর্থ বোধ না করা) আপনার সেগুলি একসাথে করা উচিত (একই কারণে আপনি আপনার পোস্টে উল্লিখিত হয়েছিলেন) এটি নিশ্চিত করে নেওয়া একটি সাধারণ ধারণা generally

এটি হ'ল আপনি যদি স্থানাঙ্কগুলি সহ সর্বদা x, y এবং z রাখেন তবে coordinateসর্বত্র তিনটি পরামিতি সঞ্চার করার চেয়ে ক্লাস করা আরও ভাল ।

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