क्या C ++ में सब कुछ के लिए वस्तुओं (आदिम प्रकारों के बजाय) का उपयोग करना समझ में आएगा?


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

हालाँकि, अधिकांश C ++ कोड मैंने देखा है कि बहुत से आदिम प्रकार का उपयोग करता है, और मुझे लगता है कि इसके लिए एक अच्छा कारण होना चाहिए। क्या किसी भी चीज़ के लिए वस्तुओं का उपयोग करना एक अच्छा विचार है, या क्या यह डाउनसाइड है कि मुझे जानकारी नहीं है?


8
"अधिकांश सी ++ कोड मैंने देखा है कि बहुत सारे आदिम प्रकार का उपयोग करता है" - दो विचार दिमाग में आते हैं: सी ++ कोड का एक बहुत सी के साथ परिचित प्रोग्रामर द्वारा लिखा जा सकता है जिसमें कमजोर अमूर्तता है; स्टर्जन के नियम
congusbongus

3
और मुझे लगता है कि यह इसलिए है क्योंकि आदिम प्रकार सरल, सीधे, तेज, चिकना और कुशल हैं। अब ओपी के उदाहरण में, कुछ नए वर्गों को पेश करना निश्चित रूप से एक अच्छा विचार है। लेकिन शीर्षक सवाल का जवाब (जहां यह "सब कुछ" कहता है) एक शानदार नहीं है!
श्री लिस्टर

1
@ मोम टाइप करने से ओपी की समस्या हल करने के लिए कुछ भी नहीं करता है।
श्री लिस्टर

1
@ कोंग्क्सू: मेरा लगभग यही विचार था, लेकिन इस अर्थ में "किसी भी भाषा में बहुत सारे कोड प्रोग्रामर द्वारा लिखे गए हो सकते हैं, जिनके पास सार के निर्माण में समस्या हो"।
डॉक ब्राउन

1
जैसा कि कहा जाता है "यदि आपके पास 17 मापदंडों के साथ एक फ़ंक्शन है, तो आप शायद कुछ याद करते हैं"।
जोरिस टिम्मरमन्स

जवाबों:


24

हाँ बिलकुल। फ़ंक्शंस / तरीके जो बहुत सारे तर्क देते हैं, एक कोड गंध है , और निम्न में से कम से कम एक को इंगित करता है:

  1. फ़ंक्शन / विधि एक ही बार में कई काम कर रही है
  2. फ़ंक्शन / पद्धति के लिए कई चीजों तक पहुंच की आवश्यकता होती है क्योंकि यह कुछ OO डिजाइन कानून के बारे में पूछ रहा है, नहीं बता रहा है या उल्लंघन नहीं कर रहा है
  3. तर्कों का वास्तव में गहरा संबंध है

यदि अंतिम एक मामला है (और आपका उदाहरण निश्चित रूप से ऐसा सुझाव देता है), तो कुछ फैंसी-पैंट "अमूर्त" करने के लिए उच्च समय है कि शांत बच्चे ओह के बारे में बात कर रहे थे, अभी कुछ दशक पहले। वास्तव में, मैं आपके उदाहरण से आगे जाऊंगा और कुछ ऐसा करूंगा:

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

(मैं जीपीएस से परिचित नहीं हूं, इसलिए यह शायद एक सही अमूर्तता नहीं है; उदाहरण के लिए, मुझे समझ में नहीं आता कि ज़ूम को किसी फ़ंक्शन के साथ क्या करना है getGPS।)

जैसे वर्गों पसंद करते हैं कृपया PixelCoordinateअधिक std::pair<T, T>है, भले ही दो एक ही डेटा है। यह सिमेंटिक मान जोड़ता है, साथ ही अतिरिक्त प्रकार की सुरक्षा का एक सा (कंपाइलर आपको एक एस पास ScreenCoordinateकरने से रोक देगा PixelCoordinate, हालांकि दोनों ही pairएस हैं।


1
उल्लेख नहीं करने के लिए आप माइक्रो-ऑप्टिमाइज़ेशन के उस छोटे से संदर्भ के द्वारा बड़ी संरचना को पास कर सकते हैं, जो सभी शांत बच्चे करने की कोशिश कर रहे हैं, लेकिन वास्तव में नहीं करना चाहिए
शाफ़्ट सनकी

6

अस्वीकरण: मैं C से C ++ को प्राथमिकता देता हूं

कक्षाओं के बजाय, मैं संरचनाओं का उपयोग करूंगा। यह बिंदु सबसे अच्छा है, क्योंकि संरचनाएं और कक्षाएं लगभग समान हैं ( एक साधारण चार्ट के लिए यहां देखें , या यह एसओ प्रश्न), लेकिन मुझे लगता है कि भेदभाव में योग्यता है।

सी प्रोग्रामर डेटा के ब्लॉक के रूप में स्ट्रक्चर्स से परिचित होते हैं, जिन्हें समूहबद्ध करते समय कुछ अधिक अर्थ होते हैं, जबकि जब मैं एक क्लैस देखता हूं, तो मुझे लगता है कि उस राज्य में हेरफेर करने के लिए कुछ आंतरिक स्थिति और तरीके हैं। एक जीपीएस कोऑर्डिनेट में राज्य नहीं होता है, बस डेटा होता है।

आपके प्रश्न से, ऐसा लगता है कि यह वही है जो आप देख रहे हैं, एक सामान्य कंटेनर, न कि एक राज्य संरचना। जैसा कि दूसरों ने उल्लेख किया है, मैं ज़ूम को अपने वर्ग में डालने की जहमत नहीं उठाऊँगा; मैं व्यक्तिगत रूप से एक डेटा प्रकार (मेरे प्रोफेसरों को बनाना Heightऔर Idकक्षाएं पसंद है) रखने के लिए बनाई गई कक्षाओं से नफरत करता हूं ।

यदि सब कुछ के लिए कक्षाएं हैं, तो एक ज़ूमलेवल पास करना असंभव होगा जहां एक भार वस्तु की उम्मीद की गई थी, इसलिए किसी फ़ंक्शन को गलत तर्क प्रदान करना अधिक कठिन होगा

मुझे नहीं लगता कि यह कोई समस्या है। यदि आपने अपने द्वारा की गई स्पष्ट चीजों को समूहीकृत करके मापदंडों की संख्या कम कर दी है, तो हेडर उन समस्याओं को रोकने के लिए पर्याप्त होना चाहिए। यदि आप वास्तव में चिंतित हैं, तो एक संरचना के साथ प्राथमिकताओं को अलग करें, जो आपको सामान्य गलतियों के लिए संकलित त्रुटियां देनी चाहिए। एक-दूसरे के बगल में दो मापदंडों को स्वैप करना आसान है, लेकिन अगर वे अलग-अलग हैं तो मुश्किल है।

इसी तरह, कुछ गैरकानूनी ऑपरेशनों के कारण गलतियाँ होंगी, जैसे कि एक Zoomlevel में GPSCoordinate जोड़ना या किसी अन्य त्रुटि को कम करना

ऑपरेटर ओवरलोड का अच्छा उपयोग।

कानूनी कार्यों का प्रतिनिधित्व करना और टाइप करना आसान होगा। यानी दो GPSCoordinates घटाना एक GPSDisplacement उपज होगा

ऑपरेटर ओवरलोड का भी अच्छा उपयोग।

मुझे लगता है कि आप सही रास्ते पर हैं। एक और बात पर विचार करना है कि यह बाकी कार्यक्रम में कैसे फिट बैठता है।


3

समर्पित प्रकारों का उपयोग करने से यह फायदा होता है कि तर्कों के क्रम को पेंच करना बहुत कठिन होता है। आपके उदाहरण फ़ंक्शन का पहला संस्करण, उदाहरण के लिए, 9 डबल्स की श्रृंखला से शुरू होता है। जब कोई इस फ़ंक्शन का उपयोग करता है, तो जीपीएस निर्देशांक के विपरीत आदेश को पेंच करना और जिम्बल कोण पास करना बहुत आसान है। इससे कीड़े को ट्रेस करने के लिए बहुत अजीब और कठिन हो सकता है। जब आप इसके बजाय केवल तीन तर्क पास करते हैं, तो यह त्रुटि संकलक द्वारा पकड़ी जा सकती है।

मैं वास्तव में एक कदम आगे जाने और प्रकारों को पेश करने पर विचार करूंगा जो तकनीकी रूप से समान हैं लेकिन एक अलग अर्थ है। उदाहरण के लिए एक वर्ग PlaneAngle3dऔर एक अलग वर्ग GimbalAngle3dहोने के बावजूद, भले ही दोनों तीन युगल का संग्रह हो। यह एक दूसरे के रूप में उपयोग करना असंभव बना देगा, जब तक कि यह जानबूझकर न हो।

मैं टाइपिडिफ्स का उपयोग करने की सलाह दूंगा जो कि आदिम प्रकारों के लिए सिर्फ उपनाम हैं ( typedef double ZoomLevel) न केवल उस कारण से, बल्कि दूसरे के लिए भी: यह आसानी से आपको बाद में प्रकार बदलने की अनुमति देता है। जब आपको एक दिन यह विचार आता है कि उपयोग floatकरना केवल उतना ही अच्छा doubleहो सकता है, लेकिन अधिक मेमोरी- और सीपीयू-कुशल हो सकता है, तो आपको बस इसे एक स्थान पर बदलना होगा, और दर्जनों में नहीं।


टाइप किए गए सुझाव के लिए +1। आपको दोनों दुनियाओं में श्रेष्ठ बनाता है: आदिम प्रकार और वस्तुएं।
कार्ल बेवेलफेल्ट

किसी टाइप सदस्य की तुलना में क्लास के सदस्य के प्रकार को बदलना कठिन नहीं है; या आप का मतलब है आदिम की तुलना में?
महुजा

2

यहाँ पहले से ही ठीक जवाब है, लेकिन एक चीज है जिसे मैं जोड़ना चाहूंगा:

उपयोग PixelCoordinateऔर PixelSizeवर्ग चीजों को बहुत विशिष्ट बनाता है। एक सामान्य Coordinateया Point2Dवर्ग शायद आपकी आवश्यकताओं के अनुरूप हो। ए Point2Dको सबसे सामान्य बिंदु / वेक्टर संचालन को लागू करने वाला एक वर्ग होना चाहिए। आप इस तरह के एक वर्ग भी सामान्य रूप से लागू कर सकता है ( Point2D<T>जहां टी हो सकता है intया doubleया कुछ और)।

2D प्वाइंट / वेक्टर ऑपरेशन बहुत सारे 2D ज्यामिति प्रोग्रामिंग कार्यों के लिए बहुत आम हैं कि मेरे अनुभव से इस तरह के निर्णय से मौजूदा 2 डी संचालन के पुन: उपयोग की संभावना बढ़ जाएगी। आप प्रत्येक के लिए उन्हें फिर से लागू करने के लिए की जरूरत से बचने जाएगा PixelCoordinate, GPSCoordinate"whatsover" -Coordinate वर्ग बार-बार।


1
struct PixelCoordinate:Point2D<int>यदि आप उचित प्रकार की सुरक्षा चाहते हैं तो आप भी कर सकते हैं
शाफ़्ट फ़्रीक

0

इसलिए मैं इसे कुछ इस तरह से देखना चाहता हूं:

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

यह मुझे पहली विधि की तुलना में काफी पठनीय और सुरक्षित प्रतीत होता है।

यह [अधिक पठनीय] है। यह एक अच्छा विचार भी है।

लेकिन क्या यह PixelCoordinate और PixelSize वर्गों को बनाने के लिए समझ में आता है?

यदि वे विभिन्न अवधारणाओं का प्रतिनिधित्व करते हैं, तो यह समझ में आता है (अर्थात, "हाँ।")।

या मैं सिर्फ std का उपयोग करके बेहतर होगा :: प्रत्येक के लिए जोड़ी।

आप करके शुरू कर सकते हैं typedef std::pair<int,int> PixelCoordinate, PixelSize;। इस तरह, आप शब्दार्थ को कवर करते हैं (आप अपने ग्राहक कोड में पिक्सेल निर्देशांक और पिक्सेल आकार के साथ काम कर रहे हैं, न कि std :: जोड़े के साथ) और यदि आपको विस्तार करने की आवश्यकता है, तो आपको बस एक वर्ग के साथ टाइप किए गए स्थान को बदलना चाहिए और आपका क्लाइंट कोड होना चाहिए। न्यूनतम बदलाव की आवश्यकता है।

और क्या यह मतलब है कि एक ज़ूमलेवल क्लास है, या मुझे सिर्फ एक डबल का उपयोग करना चाहिए?

आप इसे भी टाइप कर सकते हैं, लेकिन मैं doubleतब तक उपयोग करूंगा जब तक मुझे इससे जुड़ी कार्यक्षमता की आवश्यकता होगी जो एक डबल के लिए मौजूद नहीं है (उदाहरण के लिए, एक ZoomLevel::defaultमान रखने के लिए आवश्यक होगा कि आप एक वर्ग को परिभाषित करें, लेकिन जब तक आपके पास ऐसा कुछ न हो कि, इसे एक डबल रखें)।

सब कुछ के लिए कक्षाओं का उपयोग करने के पीछे मेरा अंतर्ज्ञान इन मान्यताओं पर आधारित है [संक्षिप्तता के लिए छोड़ दिया]

वे मजबूत तर्क हैं (आपको हमेशा सही ढंग से उपयोग करने के लिए अपने इंटरफेस को आसान बनाने और गलत तरीके से उपयोग करने में मुश्किल होना चाहिए)।

हालाँकि, अधिकांश C ++ कोड मैंने देखा है कि बहुत से आदिम प्रकार का उपयोग करता है, और मुझे लगता है कि इसके लिए एक अच्छा कारण होना चाहिए।

कारण हैं; बहुत सारे मामलों में, वे कारण अच्छे नहीं हैं। ऐसा करने का एक वैध कारण प्रदर्शन हो सकता है, लेकिन इसका मतलब है कि आपको इस तरह के कोड को अपवाद के रूप में देखना चाहिए, न कि एक नियम के रूप में।

क्या किसी भी चीज़ के लिए वस्तुओं का उपयोग करना एक अच्छा विचार है, या क्या यह डाउनसाइड है कि मुझे जानकारी नहीं है?

यह सुनिश्चित करने के लिए आम तौर पर एक अच्छा विचार है कि यदि आपके मूल्य हमेशा एक साथ दिखाई देते हैं (और इसके अलावा कोई मतलब नहीं है) तो आपको उन्हें एक साथ समूह में रखना चाहिए (उन्हीं कारणों के लिए जो आपने अपनी पोस्ट में उल्लेख किया है)।

यही है, यदि आप निर्देशांक के साथ हैं कि हमेशा x, y, और z हैं, तो coordinateकक्षा को हर जगह तीन मापदंडों से प्रसारित करने से बेहतर है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.