कितनी दूर जाने के लिए टाइप की तरह आदिम प्रकार के साथ आदिम


14

मैंने C ++ कोड देखा है जैसे कि कई typedefएस के साथ निम्नलिखित ।

typedefC ++ प्राइमेटिव का उपयोग करने के विपरीत इस तरह से कई एस का उपयोग करने के क्या लाभ हैं ? क्या एक और दृष्टिकोण है जो उन लाभों को भी प्राप्त कर सकता है?

अंत में, डेटा को सभी मेमोरी में संग्रहीत किया जाता है या तार पर बिट्स और बाइट्स के रूप में प्रेषित किया जाता है, क्या यह वास्तव में मायने रखता है?

types.h:

typedef int16_t Version;
typedef int32_t PacketLength;
typedef int32_t Identity;
typedef int32_t CabinetNumber;
typedef int64_t Time64;
typedef int64_t RFID;
typedef int64_t NetworkAddress;
typedef int64_t PathfinderAddress;
typedef int16_t PathfinderPan;
typedef int16_t PathfinderChannel;
typedef int64_t HandsetSerialNumber;
typedef int16_t PinNumber;
typedef int16_t LoggingInterval;
typedef int16_t DelayMinutes;
typedef int16_t ReminderDelayMinutes;
typedef int16_t EscalationDelayMinutes;
typedef float CalibrationOffset;
typedef float AnalogValue;
typedef int8_t PathfinderEtrx;
typedef int8_t DampingFactor;
typedef int8_t RankNumber;
typedef int8_t SlavePort;
typedef int8_t EventLevel;
typedef int8_t Percent;
typedef int8_t SensorNumber;
typedef int8_t RoleCode;
typedef int8_t Hour;
typedef int8_t Minute;
typedef int8_t Second;
typedef int8_t Day;
typedef int8_t Month;
typedef int16_t Year;
typedef int8_t EscalationLevel;

यह कोशिश करना तर्कसंगत लगता है और यह सुनिश्चित करने के लिए कि एक ही प्रकार का उपयोग हमेशा ओवरफ्लो से बचने के लिए किसी विशेष चीज के लिए किया जाता है, लेकिन मैं अक्सर कोड देखता हूं जहां "इंट" का उपयोग केवल हर जगह बहुत अधिक किया गया है। typedefIng अक्सर कोड है कि इस तरह हालांकि एक सा लग रहा है करने के लिए नेतृत्व करता है:

DoSomething(EscalationLevel escalationLevel) {
    ...
}

जो तब मुझे आश्चर्यचकित करता है कि कौन सा टोकन वास्तव में पैरामीटर का वर्णन कर रहा है: पैरामीटर प्रकार या पैरामीटर नाम?


2
IMHO, एक बहुत व्यर्थ व्यायाम की तरह लगता है, लेकिन मुझे यकीन है कि कुछ लोग असहमत होंगे ...
निम

1
वे प्रकार चर नामों की तरह दिखते हैं।
कप्तान जिराफ

11
ध्यान दें कि यह धारणा बनाता है कि यह टाइप-सुरक्षित है, लेकिन यह बिल्कुल भी नहीं है - टाइपेडिफ्स केवल उपनाम बनाते हैं, लेकिन Minuteएक फ़ंक्शन के लिए एक उदाहरण के रूप में घोषित किए जाने से कुछ भी नहीं रोकता है Second
जेसपर

2
@ मर्क: इसे दूसरे तरीके से देखें। यदि आप पूर्णांक प्रकार तय करने में कोई गलती करते हैं, या भविष्य में नई आवश्यकताएं सामने आती हैं, और इसलिए आप इसे बदलना चाहते हैं, तो क्या आप एक एकल टाइपफ़ीड बदलना चाहते हैं या आप एक वर्ष में हेरफेर करने वाले प्रत्येक फ़ंक्शन के लिए कोड खोजना चाहेंगे, और अपना हस्ताक्षर बदलो 640k किसी के लिए पर्याप्त है, और वह सब। टंकण के लिए संगत यह है कि लोग गलती से या जानबूझकर कोड लिखते हैं जो इस तथ्य पर निर्भर करता है कि वर्ष ठीक 16 बिट्स है, फिर यह बदल जाता है और उनका कोड टूट जाता है।
स्टीव जेसोप

1
@ जेस जेसोप: मैं तय नहीं कर सकता कि क्या आपको लगता है कि यह एक अच्छा या बुरा विचार है :-) पहला हिस्सा पक्ष में लगता है, बाद वाला। मुझे लगता है कि यह तो पेशेवरों और विपक्ष है।

जवाबों:


13

एक पैरामीटर के नाम का वर्णन करना चाहिए कि इसका क्या मतलब है - आपके मामले में वृद्धि का स्तर। प्रकार यह है कि मान का प्रतिनिधित्व कैसे किया जाता है - जैसा कि आपके उदाहरण में टाइपफ़ीड्स जोड़ना फ़ंक्शन-हस्ताक्षर के इस हिस्से को बाधित करता है, इसलिए मैं इसकी सिफारिश नहीं करूंगा।

टंकण के लिए टाइपफेड उपयोगी होते हैं, या यदि आप कुछ मापदंडों के लिए उपयोग किए जाने वाले प्रकार को बदलना चाहते हैं, उदाहरण के लिए जब 32 बिट से 64 बिट प्लेटफॉर्म पर माइग्रेट करते हैं।


यह आम सहमति तब लगती है। तो क्या आप आम तौर पर सिर्फ "int" से चिपके रहेंगे? डेटा ट्रांसफर करने की बात आने पर मुझे इस ऐप में बहुत कुशल होना चाहिए, तो क्या यह क्रमांकन के दौरान int16_t (या किसी विशेष तत्व के लिए जो भी सबसे बड़ा प्रतिनिधित्व प्रकार की आवश्यकता है) में परिवर्तित होने का मामला होगा?

@ मर्क: हाँ, यह है कि आप इसे कैसे करना चाहिए। उपयोग किए गए डेटा-प्रकारों के आकार को व्यक्त करने के लिए टाइपडेफ़ का उपयोग करें, लेकिन विभिन्न संदर्भों में उपयोग किए गए एक ही प्रकार को अलग न करें।
ब्योर्न पोलेक्स

धन्यवाद - और बस स्पष्ट करने के लिए, आप कोड में आमतौर पर int के बजाय int8_t का उपयोग करके परेशान नहीं करेंगे .. मुझे लगता है कि मेरी मुख्य चिंता "पहचान" की तरह कुछ थी जो वास्तव में एक डेटाबेस द्वारा उत्पन्न एक पहचान है। फिलहाल यह 32 बिट है, लेकिन मुझे यकीन नहीं है कि अगर यह अंततः 64 बिट बन सकता है। इसके अलावा, कैसे int32_t बनाम int के बारे में? int आमतौर पर int32_t के समान है, लेकिन यह हमेशा नहीं हो सकता है कि मैं एक अलग मंच पर अनुमान लगा सकता हूं? मैं सोच रहा हूं कि मुझे आम तौर पर "int" से चिपके रहना चाहिए, और "int64_t" जहां neccessary .. धन्यवाद :-)

@ मर्क: टाइपसेफ के बारे में महत्वपूर्ण बात यह int32_tहै कि आपको यह सुनिश्चित करना होगा कि विभिन्न प्लेटफार्मों पर संकलन करते समय वे सही हों। यदि आप Identityकिसी बिंदु पर परिवर्तन की सीमा की अपेक्षा करते हैं , तो मुझे लगता है कि मैं सभी प्रभावित कोड में सीधे परिवर्तन करना पसंद करूंगा। लेकिन मुझे यकीन नहीं है, क्योंकि मुझे आपके विशिष्ट डिजाइन के बारे में अधिक जानने की आवश्यकता होगी। आप एक अलग प्रश्न बनाना चाहते हैं।
ब्योर्न पोलेक्स

17

पहले तो मैंने सोचा कि "क्यों नहीं" लेकिन फिर मेरे साथ यह हुआ कि यदि आप इस तरह के प्रकारों को अलग करने के लिए इतनी लंबाई में जा रहे हैं, तो भाषा का बेहतर उपयोग करें। उपनाम का उपयोग करने के बजाय, वास्तव में प्रकार को परिभाषित करते हैं:

class AnalogueValue
{
public:
    // constructors, setters, getters, etc..
private:
    float m_value;
};

इसके बीच कोई प्रदर्शन अंतर नहीं है:

typedef float AnalogueValue;
AnalogValue a = 3.0f;
CallSomeFunction (a);

तथा:

AnalogValue a (3.0f); // class version
CallSomeFunction (a);

और आपके पास पैरामीटर सत्यापन और प्रकार सुरक्षा जोड़ने के फायदे भी हैं। उदाहरण के लिए, उस कोड पर विचार करें जो आदिम प्रकारों का उपयोग करके पैसे से संबंधित है:

float amount = 10.00;
CallSomeFunction(amount);

गोलाई के मुद्दों के अलावा, यह किसी भी प्रकार की अनुमति देता है जिसे फ्लोट में परिवर्तित किया जा सकता है:

int amount = 10;
CallSomeFunction(amount);

इस मामले में यह कोई बड़ी बात नहीं है, लेकिन अंतर्निहित रूपांतरण बग का एक स्रोत हो सकता है जिसे पिन करना मुश्किल है। यहां उपयोग करने से typedefमदद नहीं मिलती है, क्योंकि वे केवल एक प्रकार का उपनाम हैं।

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

class Money {
  Decimal amount;
  Currency currency;
};

Money m(Decimal("10.00"), Currency.USD);
CallSomeFunction(m);

जब तक हम ऐसा करने के लिए कोड नहीं लिखेंगे, तब तक उस फ़ंक्शन में कुछ और नहीं होगा। आकस्मिक रूपांतरण असंभव है। हम अधिक परेशानी के बिना आवश्यकतानुसार अधिक जटिल प्रकार भी लिख सकते हैं।


1
आप अपने लिए इस वर्ग के निर्माण के लिए कुछ भयानक मैक्रो भी लिख सकते हैं। (आइए, स्किज़। आप जानते हैं कि आप चाहते हैं।)

1
इनमें से कुछ के लिए, प्रत्येक के लिए एक कस्टम वर्ग लिखने के बजाय एक प्रकार-सुरक्षित इकाइयाँ लाइब्रेरी सहायक हो सकती है ( tuoml.sourceforge.net/html/scalar/scalar.html )।
स्टीव जेसप

@ क्रिस - निश्चित रूप से एक मैक्रो नहीं है, लेकिन संभवतः एक टेम्पलेट वर्ग है। जैसा कि स्टीव बताते हैं, वे कक्षाएं पहले से ही लिखी गई हैं।
केविन क्लाइन

4
@ क्रिस: मैक्रो को BOOST_STRONG_TYPEDEFवास्तव में कहा जाता है ;)
मैथ्यू एम।

3

आदिम प्रकारों के लिए टाइपफ़ीड्स का उपयोग करना जो सी स्टाइल कोड की तरह दिखता है।

C ++ में जैसे ही आप कार्यों को ओवरलोड करने की कोशिश करते हैं, कहते हैं, EventLevelऔर Hour। यह अतिरिक्त प्रकार के नामों को बहुत बेकार बनाता है।


2

हम (हमारी कंपनी में) इसे C ++ में बहुत कुछ करते हैं। यह कोड को समझने और बनाए रखने में मदद करता है। जो टीमों के बीच लोगों को ले जाने या रिफैक्टरिंग करने के लिए अच्छा है। उदाहरण:

typedef float Price;
typedef int64_t JavaTimestmap;

void f(JavaTimestamp begin, JavaTimestamp end, Price income);

हमारा मानना ​​है कि प्रतिनिधित्व प्रकार से आयाम नाम के लिए टाइपफ़ीड बनाने के लिए यह एक अच्छा अभ्यास है। यह नया नाम एक सॉफ्टवेयर में एक सामान्य भूमिका का प्रतिनिधित्व करता है । एक पैरामीटर का नाम एक स्थानीय भूमिका है । में पसंद है User sender, User receiver। कुछ स्थानों पर यह निरर्थक हो सकता है, जैसे void register(User user), लेकिन मैं इसे समस्या नहीं मानता।

बाद में किसी को यह विचार हो सकता है कि floatबुकिंग के विशेष दौर के नियमों के कारण कीमतों का प्रतिनिधित्व करने के लिए सबसे अच्छा नहीं है, इसलिए एक डाउनलोड BCDFloat( या बाइनरी कोडित दशमलव) प्रकार को डाउनलोड करता है और टाइप करता है। ऐसा कोई खोज और प्रतिस्थापित कार्य नहीं floatहै BCDFloatजिससे इस तथ्य को कठोर किया जा सके कि आपके कोड में संभवतः कई और फ़्लोट हैं।

यह एक चांदी की गोली नहीं है और इसके अपने गुहिकायन हैं, लेकिन हमें लगता है कि यह नहीं की तुलना में इसका उपयोग करना बेहतर है।


या जैसा कि मैथ्यू एम ने स्किज़ के पद पर सुझाव दिया है कि कोई भी जा सकता है BOOST_STRONG_TYPEDEF(float, Price), लेकिन मैं एक औसत परियोजना पर नहीं जा सकता। या शायद मैं करूंगा। मुझे इस पर सोना है। :-)
नोटिनल

1

typedefमूल रूप से आपको एक के लिए एक उपनाम देने की अनुमति देता है type
यह आपको type namesबार-बार टाइप करने से बचने और अपने typeअधिक आसानी से पढ़ने योग्य बनाने की सुविधा देता है जिसमें उपनाम नाम या इरादे का संकेत देता है type

यदि आप typedefअपनी परियोजना में अधिक पठनीय नाम रखना चाहते हैं तो यह अधिक पसंद की बात है ।
आमतौर पर, मैं typedefआदिम प्रकारों का उपयोग करने से बचता हूं , जब तक कि वे टाइप किए जाने के लिए असामान्य रूप से लंबे न हों। मैं अपने पैरामीटर नामों को अधिक सांकेतिक रखता हूं।


0

मैं कभी ऐसा कुछ नहीं करूंगा। यह सुनिश्चित करना कि उन सभी का आकार एक समान है- लेकिन आपको केवल उन्हें अभिन्न प्रकार के रूप में संदर्भित करने की आवश्यकता है।


0

इस तरह से टाइप किए गए समय का उपयोग करना ठीक है जब तक कि उनका उपयोग करने वाले हवाओं को अपने अंतर्निहित प्रतिनिधित्व के बारे में कुछ भी जानने की आवश्यकता नहीं है । उदाहरण के लिए, यदि आप किसी PacketLengthवस्तु को या तो पास करना चाहते हैं printfया scanfआपको उसका वास्तविक प्रकार जानना होगा, ताकि आप सही रूपांतरण विनिर्देशक चुन सकें। इस तरह के मामलों में, टाइपराइफ सिर्फ बदले में कुछ भी खरीदे बिना एक स्तर का आक्षेप करता है; आप के रूप में अच्छी तरह से सिर्फ वस्तु के रूप में परिभाषित किया गया हो सकता है int32_t

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

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