क्या यह "# मेरे लिए अच्छा विचार है * (यह)"?


19

इस मैक्रो को कंपाइलर कमांड लाइन पैरामीटर के रूप में कुछ वैश्विक हेडर या बेहतर में परिभाषित किया जा सकता है:

#define me (*this)

और कुछ उपयोग उदाहरण:

some_header.h:

inline void Update()
{
    /* ... */
}

main.cpp:

#include "some_header.h"

class A {
public:
    void SetX(int x)
    {
        me.x = x;   
        me.Update(); 
    }

    void SomeOtherFunction()
    {
        ::Update();
    }

    /*
        100 or more lines
        ... 
    */

    void Update()
    {
        // ... 
    }

    int x;  
};

इसलिए कक्षा विधि में जब मैं एक कक्षा सदस्य का उपयोग करता हूं, तो मैं हमेशा उपयोग करता हूं me, और वैश्विक पहचानकर्ता का उपयोग करते समय मैं हमेशा उपयोग करता हूं ::। यह पाठक को कोड के साथ परिचित नहीं है (शायद कुछ महीनों के बाद खुद को) जो कुछ और देखने की आवश्यकता के बिना पहुँचा है की स्थानीय जानकारी। मैं परिभाषित करना चाहता हूं meक्योंकि मैं this->हर जगह शोर और बदसूरत का उपयोग करता हूं । लेकिन #define me (*this)एक अच्छा C ++ अभ्यास माना जा सकता है? क्या meमैक्रो के साथ कुछ व्यावहारिक समस्याग्रस्त बिंदु हैं ? और यदि आप C ++ प्रोग्रामर के रूप में meमैक्रो का उपयोग करते हुए कुछ कोड के पाठक होंगे, तो आप इसे पसंद करेंगे या नहीं?

संपादित करें: क्योंकि कई लोग तर्क का उपयोग करते हुए विशिष्ट गर्भनिरोधक नहीं करते हैं me, लेकिन सामान्य रूप से होने वाले संक्रमण ने इसे स्पष्ट कर दिया है। मुझे लगता है कि यह स्पष्ट नहीं हो सकता है कि "हर जगह यह स्पष्ट" के क्या लाभ हैं।

"हर जगह यह स्पष्ट" के क्या लाभ हैं?

  • कोड के एक पाठक के रूप में आपके पास निश्चित है कि क्या एक्सेस किया गया है और आप सत्यापित करने की तुलना में अलग-अलग चीजों पर ध्यान केंद्रित कर सकते हैं - कुछ दूर के कोड में - जो आपको लगता है कि वास्तव में एक्सेस किया गया है।
  • आप विशेष रूप से खोज फ़ंक्शन का उपयोग कर सकते हैं। खोज " this->x" आपको केवल खोज से अधिक वांछित परिणाम दे सकता है " x"
  • जब आप किसी सदस्य को हटा रहे हैं या उसका नाम बदल रहे हैं, तो संकलक आपको उन स्थानों पर मज़बूती से सूचित करता है जहाँ इस सदस्य का उपयोग किया जाता है। (कुछ वैश्विक फ़ंक्शन में एक ही नाम हो सकता है और मौजूद मौका आपको त्रुटि का परिचय दे सकता है यदि आप इसे स्पष्ट उपयोग नहीं कर रहे हैं)।
  • जब आप कोड को पुन: सक्रिय कर रहे हैं और सदस्य से गैर-सदस्यीय कार्य कर रहे हैं (बेहतर एन्कैप्सुलेशन बनाने के लिए) तो यह स्पष्ट रूप से आपको दिखाता है कि आपको कौन सा स्थान संपादित करना चाहिए और आप इसे गैर-सदस्य फ़ंक्शन पैरामीटर के रूप में दिए गए वर्ग के उदाहरण के लिए सूचक के साथ आसानी से बदल सकते हैं
  • आम तौर पर जब आप कोड बदल रहे होते हैं, तो त्रुटियों के लिए और अधिक जिम्मेदारियाँ होती हैं जब आप स्पष्ट रूप से इसका उपयोग नहीं कर रहे होते हैं जब आप हर जगह स्पष्ट उपयोग कर रहे होते हैं।
  • स्पष्ट करें कि यह स्पष्ट this m_ की तुलना में कम शोर है "जब आप बाहर से सदस्य ( object.memberबनाम object.m_member) को स्वीकार कर रहे हैं (इस बिंदु को प्राप्त करने के लिए @Kaz के लिए धन्यवाद)
  • स्पष्ट करें कि यह समस्या सभी सदस्यों - विशेषताओं और विधियों के लिए सार्वभौमिक रूप से हल करती है, जबकि “m_” या अन्य उपसर्ग केवल विशेषताओं के लिए व्यावहारिक रूप से प्रयोग करने योग्य है।

मैं इस सूची को चमकाना और बढ़ाना चाहूंगा, मुझे बताएं कि क्या आप अन्य लाभों के बारे में जानते हैं और हर जगह स्पष्ट रूप से इस मामले का उपयोग करते हैं ।


3
आपको एक ही नाम के साथ फ़ंक्शन तर्क और सदस्य होने से बचना चाहिए, साथ ही स्पष्ट "यह" से बचना चाहिए।
pjc50

4
मुझे मेरे बॉस का VB कोड याद दिलाता है। मुझे हर जगह मुझे। स्वार्थी लगता है। : पी वैसे भी, जवाब अब तक यह सब कहते हैं।
मेटलमेस्टर

19
यह एक अद्भुत विचार है! और जो लोग पायथन पृष्ठभूमि से आते हैं, उनके लिए क्यों नहीं #define self (*this)? तुम भी दोनों मैक्रोज़ मिश्रण कर सकते हैं और कुछ फाइलें VB और अन्य पायथन नकल कर रहे हैं। :)
लॉग

11
क्यों नहीं बस सभी बाहर जाना है, और कार्य करें: #include "vb.h", #Include pascal.h, या #include FOTRAN.hऔर अपने कोड में जमा करें छूने के लिए अगले व्यक्ति है TDWTF
डैन नीली

4
ओह प्लीज, बस नहीं। आप केवल विशेषताओं को घोषित करके खुद को कुछ परेशानी से बचा सकते हैं me_x
रोबोट

जवाबों:


90

नहीं ऐसा नहीं है।

प्रोग्रामर का ध्यान रखें जो आपके पास कई वर्षों से आपके कोड को बनाए रखेगा जब तक आप हरियाली चरागाहों के लिए छोड़ देते हैं और आपके द्वारा उपयोग की जाने वाली भाषा के सामान्य सम्मेलनों का पालन करते हैं। C ++ में, आपको लगभग कभी लिखना नहीं पड़ता है this, क्योंकि वर्ग को प्रतीक रिज़ॉल्यूशन ऑर्डर में शामिल किया जाता है और जब एक प्रतीक वर्ग के दायरे में पाया this->जाता है , तो निहित होता है। तो बस यह मत लिखो जैसे हर कोई करता है।

यदि आप अक्सर भ्रमित हो जाते हैं कि कौन से प्रतीक वर्ग दायरे से आते हैं, तो सामान्य दृष्टिकोण सदस्यों (क्षेत्रों और कभी-कभी निजी तरीकों के लिए सामान्य नामकरण पैटर्न का उपयोग कर रहा है; मैंने इसे सार्वजनिक तरीकों के लिए उपयोग नहीं किया है)। आम लोगों के साथ प्रत्यय लगाना शामिल _या साथ लगाकर m_या m


12
"C ++ में, आपको लगभग कभी भी यह लिखना नहीं पड़ता है" यह सवाल के लिए पूरी तरह से असंबंधित सम्मेलन है। कुछ लोग (मेरे जैसे) thisस्पष्ट रूप से यह स्पष्ट करने के लिए लिखना पसंद करते हैं कि चर विधि के लिए स्थानीय नहीं है। यहां सवाल यह है कि क्या मैक्रो meमौजूद होना चाहिए, न कि क्या thisऐसा कुछ है जिसका उपयोग किया जाना चाहिए।
मेहरदाद

8
@ मेहरदाद: क्योंकि ओपी स्पष्ट रूप से कहता है कि वह me.इसके बजाय उपयोग कर रहा है this->। चूँकि इसकी कोई आवश्यकता this->नहीं है me.और इस प्रकार स्थूल की कोई आवश्यकता नहीं है।
मार्टिन

11
@ लोकीअस्तारी: कुछ भी नहीं सवाल में भी ओपी पर दूर से संकेत देता है कि क्या this->"आवश्यक" है। वास्तव में, ओपी का कहना है कि वह this->इस तथ्य के बावजूद उपयोग कर रहा है कि यह आवश्यक नहीं है। सवाल के बारे में है कि क्या है me.इस्तेमाल किया जाना चाहिए के बजाय this-> , जो इस सवाल का जवाब वास्तव में उत्तर नहीं देता।
मेहरदाद

4
@ मेहरदाद: लेकिन केवल हां या ना में जवाब देना बहुत ही उबाऊ जवाब देता है। इस प्रकार स्पष्टीकरण आमतौर पर यह समझाने में काफी उपयोगी है कि उत्तर कैसे पहुंचा जाता है (इसका उत्तर कैसे दिया जाए )। निष्कर्ष का उपयोग नहीं करना है क्योंकि ओपी का उपयोग करने के बारे में शुरू करने के लिए गलत रवैया है thisऔर इस तरह उस बिंदु पर एक चर्चा पूरी तरह से संतुलित निष्कर्ष प्राप्त करने के लिए आवश्यक है।
मार्टिन

1
+1 की व्याख्या करने के लिए, केवल कहने के बजाय "नहीं, यह एक बुरा अभ्यास है।"
user253751

42

इसलिए, आप एक नई भाषा बनाना चाहते हैं। फिर ऐसा करें, और C ++ को अपंग न करें।

ऐसा नहीं करने के कई कारण हैं:

  1. हर सामान्य कोडिंग मानक मैक्रोज़ से बचने का सुझाव देगा ( यहाँ है क्यों )
  2. ऐसे मैक्रो के साथ कोड बनाए रखना कठिन है। C ++ में हर कोई प्रोग्रामिंग जानता है कि क्या thisहै, और इस तरह के मैक्रो को जोड़कर, आप वास्तव में एक नया कीवर्ड जोड़ रहे हैं। क्या होगा अगर हर कोई अपनी पसंद का कुछ परिचय दे? कोड कैसा दिखेगा?
  3. आपको कुछ विशेष मामलों को छोड़कर (*this).या बिल्कुल भी उपयोग नहीं करना चाहिए this->( यह उत्तर देखें और "यह->" खोजें)

आपका कोड अलग नहीं है #define R return, जिसे मैंने वास्तविक कोड में देखा था। कारण? कम टाइपिंग!


विषय से थोड़ा हटकर, लेकिन यहां मैं बिंदु 3 पर विस्तार करने जा रहा हूं (उपयोग न करें (*this).या this->कक्षा में)।

सबसे पहले, (*this).या this->ऑब्जेक्ट के सदस्य चर या कार्यों तक पहुंचने के लिए उपयोग किया जाता है। इसका उपयोग करना अर्थहीन है और इसका अर्थ अधिक टाइपिंग है। इसके अलावा, इस तरह के कोड को पढ़ना अधिक कठिन है, क्योंकि अधिक पाठ है। इसका मतलब है कठिन रखरखाव।

तो, ऐसे कौन से मामले हैं जिनका आपको उपयोग करना है this->?

(ए) तर्क के नाम का दुर्भाग्यपूर्ण चयन।

इस उदाहरण में, this->आवश्यक है, क्योंकि तर्क का सदस्य चर के समान नाम है:

struct A {
  int v;
  void foo( int v ) {
    this->v =v;
  }
};

(ख) जब टेम्पलेट्स और विरासत के साथ काम कर (देखें इस )

यह उदाहरण संकलित करने में विफल रहेगा, क्योंकि संकलक को यह पता नहीं है कि किस चर को नाम दिया vगया है।

template< typename T >
struct A {
  A(const T& vValue):v(vValue){}

  T v;
};

template< typename T >
struct B : A<T>
{
    B(const T& vValue):A<T>(vValue){}

    void foo( const T & newV ) {
      v = newV;
    }
};

1
"तो, आप एक नई भाषा बनाना चाहते हैं। फिर ऐसा करें, और c ++ को अपंग न करें।" - मैं असहमत हूं। C और C ++ की एक प्रमुख ताकत उनका लचीलापन है। ओपी C ++ को अपंग नहीं कर रहा है, बस अपने लचीलेपन का उपयोग एक विशेष तरीके से करता है ताकि उसे या उसके कोड को आसान बना सके।
user253751

2
@ मिनीबिस राइट। जो उसके लिए आसान है, बाकी सब के लिए कठिन है। जब आप किसी टीम में काम करते हैं, तो कोड में इस तरह के बकवास लगाने से आप बहुत अनुकूल नहीं होंगे।
B:56ови।

2
आपका उत्तर "परिभाषित बुरे हैं" से अलग नहीं है।
मिस्टर लिस्टर

7
@ मैरिस्टर मेरा जवाब है "बेवकूफ परिभाषित बुराई हैं"। प्रश्न में मैक्रो का उपयोग करना बेवकूफी है, और जैसा कि मैंने दिखाया, बिल्कुल भी ज़रूरत नहीं है। कोड अच्छा और भी बेहतर के बिना है *this.औरthis->
BЈовић

1
@ मेहरदाद क्या लोग अभी भी सदस्य चर में उपसर्ग और प्रत्यय जोड़ रहे हैं? मुझे लगा कि क्लीन कोड जैसी किताबों के साथ "तय" किया गया था । प्री-सी ++ 11 this->जितना ही उपयोगी है auto। दूसरे शब्दों में, यह सिर्फ कोड शोर को बढ़ाता है।
B:05овиЈ

26

मेरा सुझाव है कि ऐसा न करें। यह एक पाठक देता है जो आपके मैक्रो के साथ परिचित नहीं है एक बड़ा " डब्ल्यूटीएफ " जब भी वह यह देखता है। किसी भी वास्तविक आवश्यकता के बिना आम तौर पर स्वीकार किए गए लोगों पर "नए सम्मेलनों" का आविष्कार करते समय कोड अधिक पठनीय नहीं होता है।

इसका उपयोग-> हर जगह बहुत शोर और बदसूरत है

यह आपको ऐसा लग सकता है, हो सकता है कि आपने कीवर्ड का उपयोग करके भाषाओं में बहुत सारी प्रोग्रामिंग की हो me(विजुअल बेसिक, मुझे लगता है?)। लेकिन वास्तव में यह सिर्फ इसके आदी होने का मामला है - this->बहुत छोटा है, और मुझे लगता है कि अधिकांश अनुभवी सी ++ प्रोग्रामर आपकी राय से असहमत होंगे। और उपरोक्त मामले में, न तो उपयोग करना this->या उपयोग meकरना उचित है - आप सदस्य कार्यों के अंदर डेटा सदस्यों को एक्सेस करते समय उन कीवर्ड को छोड़कर अव्यवस्था की सबसे छोटी राशि प्राप्त करते हैं।

यदि आप चाहते हैं कि आपके निजी सदस्य चर स्थानीय लोगों से अलग हों, तो m_उपसर्ग के रूप में कुछ लिंक जोड़ें , या उन्हें प्रत्यय के रूप में एक अंडरस्कोर (लेकिन जैसा कि आप यहां देख सकते हैं , यहां तक ​​कि यह सम्मेलन कई लोगों के लिए "बहुत शोर" है)।


12
_प्रत्यय होना चाहिए ; उपसर्ग के रूप में यह मानक पुस्तकालयों और विक्रेता एक्सटेंशन के आंतरिक प्रतीकों के लिए आरक्षित है।
Jan Hudec

4
@JanHudec केवल अगर यह __(दो अंडरस्कोर) या एक अंडरस्कोर के साथ शुरू होता है, उसके बाद कैपिटल लेटर। एक एकल अंडरस्कोर जिसके बाद एक निचला केस अक्षर ठीक है, जब तक कि यह वैश्विक नामस्थान में नहीं है।
एरिक फिन

1
@EricFinn: मैंने दो नियमों को एक में जोड़ दिया। दो अंडरस्कोर या अंडरस्कोर जिसके बाद कैपिटल लेटर होता है, आंतरिक प्रतीकों के लिए होता है और सिंगल अंडरस्कोर जिसके बाद लोअर लेटर लेटर सिस्टम-विशिष्ट एक्सटेंशन के लिए होता है। अनुप्रयोगों का उपयोग नहीं करना चाहिए।
Jan Hudec

@JHHudec सिस्टम-विशिष्ट एक्सटेंशन के लिए नियम से अवगत नहीं था। मैं आपकी टिप्पणी के लिए कुछ संदर्भ प्रदान करने के लिए अपनी पिछली टिप्पणी छोड़ दूंगा, हालांकि।
एरिक फिन

2
@ जानहुडेक: लोअरकेस सिस्टम-विशिष्ट एक्सटेंशन के लिए है? क्या आप C ++ मानक के उस हिस्से का संदर्भ पोस्ट कर सकते हैं जो यह इंगित करता है?
मेहरदाद

18

कृपया इसे मत करो! मैं एक बड़े कोड बेस के साथ सामना करने की कोशिश कर रहा हूं, जहां मैक्रो टाइपिंग को बचाने के लिए सभी जगह हैं। मुझे इसे फिर से परिभाषित करने के बारे में बुरी बात यह है कि प्रीप्रोसेसर इसे हर जगह बदल देगा, यहां तक ​​कि जहां यह गुंजाइश नहीं है / लागू नहीं होता है, उदाहरण के लिए एक स्टैंड-अलोन फ़ंक्शन, आपके साथी सहयोगी का स्थानीय चर हो सकता है, मुझे कहीं और बुलाया जा सकता है .. (ओं) वह खुश डिबगिंग नहीं होगा ... आप अंत में मैक्रोज़ जो आप सभी scopes में उपयोग नहीं कर सकते हैं।


6

नहीं!

बस उस भ्रम की कल्पना करें जो किसी # # हेडर को शामिल करने पर होगा, जो आपकी चाल को नहीं जानता है, और कहीं और उनकी फ़ाइल में उनके पास "मुझे" नामक एक चर या फ़ंक्शन है। जो भी अयोग्य त्रुटि संदेश मुद्रित होगा, वे बुरी तरह से भ्रमित होंगे।


व्यवहार में, वे अपनी IDE के साथ "me" पर माउस-ओवर करने और परिभाषा देखने की काफी संभावना रखते हैं।
user253751

2
@ मिनीबिस: व्यवहार में, हालांकि, वे भी कुछ ऐसा ही कह सकते हैं जैसे "यह बकवास किसने लिखा है?"। : P
cHao

@ मिनीबिस: मैं जिन शीर्ष कोडर के साथ काम करता हूं उनमें से अधिकांश माउस का उपयोग नहीं करते हैं - यह बहुत धीमा है।
JBRWilkinson

वास्तव में: एक हेडर में यह shoving वास्तविक समस्या है। यदि आप इसे अपने cpp फ़ाइल में उपयोग करते हैं तो मुझे कोई समस्या नहीं दिखती है। यदि हमारे पास मानक के रूप में व्यावहारिक धक्का था, तो मैं सलाह दूंगा कि यह कैसे हेडर में किया जाए, लेकिन हम ऐसा नहीं करते हैं। मेरे बाद दोहराएँ। #defines वैश्विक हैं।
यहोशू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.