2012-02-29 11 views
8

संपादित करें: यह नीचे प्रस्तुत (सरलीकृत) मामले में सर्वोत्तम अभ्यास के बारे में एक चर्चा है। जो भी उपकरण, कोडिंग शैली या कुछ और जिसे आप सुझाव देना चाहते हैं, इसे पोस्ट करें। धन्यवाद।क्या सी ++ कन्स्ट्रक्टर (और विनाशक) घोषित/परिभाषित करने का कोई विशेष तरीका है

कक्षा के नाम को डुप्लिकेट किए बिना सीटीआर/डाटर घोषित करने या परिभाषित करने के कोई विशेष तरीके क्यों नहीं हैं? यह कष्टप्रद है, खासकर जब कक्षा का नाम बदलना प्रोटोटाइप और समाप्त होता है।

क्या मेरा मतलब है इस तरह typedef के साथ कुछ है:

struct SomeClassThatDoesSomething { 
    typedef SomeClassThatDoesSomething ThisClass; 
    ThisClass() { PrepareToDie(); } 
    ThisClass(int a) : _a(a) { PrepareToDie(); } 
    ThisClass(float a, int b) : _b(a), _a(b) { PrepareToDie(); } 
    ThisClass(float a, char * b) : _b(a), _c(b) { PrepareToDie(); } 
    ThisClass(char * a, int b) : _c(a), _a(b) { PrepareToDie(); } 
    ThisClass(ThisClass &rhs) { } 
    ~ThisClass() {} 
    void Burn() {} 
    void PrepareToDie() {} 
    int _a; 
    float _b; 
    char *_c; 
}; 

struct SomeDerivedClassThatDoesSomething : public SomeClassThatDoesSomething { 
    typedef ThisClass BaseClass; 
    typedef SomeDerivedClassThatDoesSomething ThisClass; 
    ThisClass(BaseClass &is_not_amused) : BaseClass(is_not_amused) { BaseClass::_a = 1; PrepareToDie(); } 
    ThisClass(float a, char * b) : BaseClass(b, a) {} 
    ~ThisClass() { BaseClass::Burn(); } 
    unsigned int _a; // Different semantics up the tree. 
}; 

//EDIT: Consider this: Enforce export name decoration policy. 
#define DLL_API __declspec(dllexport) 
// ... or dllimport - not the point here 
#define def_export_struct(name) struct C##name; typedef C##name *P##name; struct DLL_API C##name 

def_export_struct(SomeOtherClassThatDoesSomething) : public SomeDerivedClassThatDoesSomething 
{ 
//... 
}; 
namespace mass_destruction { 
    def_export_struct(Int) 
    { 
    //... (The point is that search and replace gets very unreliable in big projects) 
    } 
}; 

यह केवल ctors के लिए और केवल MSVC पर काम करता है; मैं इसका उपयोग कर रहा हूं और, हालांकि एक बड़ी सुविधा नहीं है, यह जीवन को आसान बनाता है। यह एक मामूली उदाहरण है, लेकिन एक काफी जटिल संरचना की कल्पना करो। (एक आसान दुष्प्रभाव यह भी है कि आपके नाम को ट्रैक किए बिना कक्षा में उपनाम है।) क्या मुझे कुछ याद आ रही है? क्या मैं वास्तव में अकेला हूं जिसकी आवश्यकता है? बिंदु यह नहीं है कि यह संकलित करता है, बिंदु यह है कि मुझे यह आंशिक रूप से मेरे लिए जगह पर काम कर रहा है और यह आश्चर्य करता है। जब तक मैं मानक हिट नहीं करता ... (यह अनुपालन चर्चा नहीं है।)

+4

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

+1

यह वास्तव में स्पष्ट नहीं है कि आप क्या पूछ रहे हैं। चाहे ऐसी सुविधा मौजूद है, या * क्यों * यह अस्तित्व में नहीं है, कुछ और? और कहकर आप पहले से ही इस तरह की सुविधा के बारे में जानते हैं और आप अनुपालन में रूचि नहीं रखते हैं, यह जानना मुश्किल है कि आप और क्या चाहते हैं। – jalf

+4

@ BjörnPollex: सी ++ के लिए कैपेबिलिट्स को रीफैक्टरिंग आम तौर पर अपने जावा/सी # समकक्षों के पीछे पीछे हट रहे हैं। और उस तरफ, हर कोई आईडीई का उपयोग नहीं करता है, और शायद ही कभी भाषा सुधार करने के लिए आईडीई का उद्देश्य * अनावश्यक * – jalf

उत्तर

6

कभी खोज और प्रतिस्थापन के बारे में सुना?

मुझे लगता है कि ज्यादातर लोग या तो ex, vim, sed का उपयोग करते हैं। इत्यादि: s/search/replace/g या उनके वर्गों के नाम को बदलने के बराबर, या उन्हें इस बदलाव की कमी से परेशान होने के लिए अक्सर परिवर्तित न करें।

आप इस नम्रतापूर्वक करने के लिए एक #define इस्तेमाल कर सकते हैं:

#define THIS_CLASS MyLongClassNameThatIChangeLotsAndLots 
class THIS_CLASS{ 
    THIS_CLASS() { PrepareToDie(); } 
    THIS_CLASS(int a) : _a(a) { PrepareToDie(); } 
    THIS_CLASS(float a, int b) : _b(a), _a(b) { PrepareToDie(); } 
    THIS_CLASS(float a, char * b) : _b(a), _c(b) { PrepareToDie(); } 
    THIS_CLASS(char * a, int b) : _c(a), _a(b) { PrepareToDie(); } 
    THIS_CLASS(THIS_CLASS &rhs) { } 
    ~THIS_CLASS() {} 
}; 
#undef THIS_CLASS 

क्या परेशान है, मैं इस बात से सहमत होगा, एक मानक तरीका एक प्रकार का आधार वर्ग (ते) का उल्लेख करने की कमी है - - मैं सामान्य रूप से निजी तौर पर typedef ... base_t कक्षाओं में है, तो का उपयोग करें कि initialiser सूचियों के लिए, आदि

+1

readytoDie() ... +1 – UmNyobe

+0

मैं भी sed का उपयोग करता हूं, लेकिन यह कुछ सिस्टमों में उपलब्ध नहीं है। आपका मैक्रो ज्यादा मदद नहीं करता है क्योंकि कक्षाओं में अलग-अलग रचनाकार हो सकते हैं। आप सामान्य ctors के एक न्यूनतम सेट भी नहीं मान सकते हैं। मुझे व्यक्तिगत रूप से लगता है कि यह समय के लायक नहीं है। – jweyrich

+0

एक और समस्या यह है कि मैक्रो रेडिफिनिशन #pragma push_macro ("THIS_CLASS") और #pragma pop_macro ("THIS_CLASS") के साथ बदसूरत हो जाता है। करने योग्य, लेकिन ट्रैक करने के लिए कठिन है। मैं सामान्य परिभाषाओं से कम के लिए ऐसी चीज को बचाऊंगा। – ActiveTrayPrntrTagDataStrDrvr

3

अपने वर्ग के नाम frustratingly घना हो रही है, namespace का अधिक इस्तेमाल कर रही है पर विचार करें।

namespace, using के साथ संयुक्त आपके टाइपनाम केवल प्रत्येक संदर्भ मांग के रूप में वर्बोज़ बनाने के लिए बहुत अच्छा है।

namespace Something 
{ 
    struct Derived : public SomeClass 
    { 
    Derived() {...etc.} 

    } 
} 
+0

है, लंबे नाम शीर्ष पर शीर्ष पर हैं। लेकिन आपके उत्तर पर वापस: क्या यह वास्तव में खोज और कड़ी जगह नहीं बदलता है? यह कई डुप्लिकेट नाम पेश करेगा। – ActiveTrayPrntrTagDataStrDrvr

+0

@ उपयोगकर्ता 1240436: यह एस/आर कठिन बनाता है, हां। मेरा जवाब वास्तव में आपके संपादन के बाद लागू नहीं होता है। –

+0

यह अभी भी एक छोटी परियोजना की योजना बनाने के तरीके के रूप में उपयोगी है। – ActiveTrayPrntrTagDataStrDrvr

संबंधित मुद्दे