2012-07-25 14 views
5

मैं एक पुस्तकालय बना रहा हूं जिसमें 3-डी निर्देशांक शामिल हैं, और पता चला कि 3-डी कोण के घटकों के लिए दो नाम हैं: यॉ-पिच-रोल और हेडिंग-कक्षा संदर्भ सदस्य उसी वर्ग में अन्य सदस्य को इंगित करता है

struct Angle { 
    float heading; 
    float elevation; 
    float bank; 
    float &yaw = heading; 
    float &pitch = elevation; 
    float &roll = bank; 

    // Some Constructors (copy and assignment have to be made manually) 
} 

कौन से दो नाम-योजनाओं के बीच संकेतन बराबर रखने को लाभ मिलता है: ऊंचाई बैंक

तो मैं निम्नलिखित (C++ 11 किया) बनाया है। उदाहरण के लिए:

Angle angle; 
rotate(angle.yaw); // this is equivalent to rotate(angle.heading) 

मैं अगर संकलक यह पता लगाने जाएगा संदर्भ अनावश्यक थे, या अगर यह संरचना में संकेत दिए गए रखेंगे सोच रहा था।

इसके अलावा, क्या एक सदस्य के लिए दो नाम रखने का एक बेहतर तरीका है?

उत्तर

2

मैं सोच रहा था, या अगर यह संरचना में संकेत दिए गए रखना होगा:

तुम बस कुछ getters और setters (स्यूडोकोड) बना सकते हैं।

99.9% मामलों में, पॉइंटर्स संरचना में रखा जाएगा। मुझे संकलक इकाइयों पर उन्हें बाहर करने के लिए संकलक के लिए कोई रास्ता नहीं दिख रहा है। एएसपी क्योंकि आपका वाक्यविन्यास अमान्य है, और आपको कन्स्ट्रक्टर में संदर्भों को प्रारंभ करना होगा, जो बहुत अच्छी तरह छुपाया जा सकता है। इसलिए यह जानने का कोई तरीका नहीं होगा कि कौन से संदर्भ संदर्भ सदस्य हैं।

कुछ प्रदर्शन ओवरहेड भी हो सकता है। उदाहरण के लिए:

float x = a.elevation; 
013F13E0 fld   dword ptr [ebp-18h] 
013F13E3 fstp  dword ptr [x] 
    float y = a.pitch; 
013F13E6 mov   eax,dword ptr [ebp-0Ch] 
013F13E9 fld   dword ptr [eax] 
013F13EB fstp  dword ptr [y] 

दरअसल, आंतरिक रूप से, संदर्भ पॉइंटर्स की तरह कार्य करते हैं। तो अतिरिक्त mov उस पॉइंटर को संदर्भित करने के लिए बनाता है।

हालांकि मैं इसके बारे में चिंता नहीं करता, इसके बजाय शैली की परवाह करता हूं। और एक ही चीज़ के लिए दो सदस्य लेखांकन कर रहे हैं ... बस गलत लगता है।

0

इतने सारे सार्वजनिक चर क्यों बनाते हैं? यदि संकलक यह पता लगाने जाएगा संदर्भ अनावश्यक थे

struct Angle { 
    float heading; 
    float elevation; 
    float bank; 

    float& yaw() const { 
     return heading; 
    } 
    float& pitch() const { 
     return elevation; 
    } 
    float& roll() const { 
     return bank; 
    } 

    //etc... 

    // Some Constructors (copy and assignment have to be made manually) 
} 
+0

मैं मूल रूप से एक ही चीज़ लिख रहा था :) लेकिन, क्या आप वास्तविक विशेषताओं के संदर्भ वापस नहीं लेना चाहिए? अन्यथा, उन्हें वैकल्पिक नाम के माध्यम से संशोधित नहीं किया जा सकता है। असल में, तरीकों के दो सेट प्रदान किए जाने चाहिए: 'कॉन्स फ्लोट और यॉ() कॉन्स; 'और' फ्लोट एंड यॉ();'। फिर यह स्थिर 'कोण' के संदर्भों के साथ भी काम करेगा। – betabandido

+0

@betabandido मेरे कोड को संपादित करें^_^जैसा कि मैंने कहा था कि यह 'छद्म कोड' है। जाहिर है यह पूरी तरह से इस तरह नहीं होगा^_^(और मैं रिटर्न संदर्भ बीटीडब्ल्यू: -पी) – Neal

+0

@ लचियनग्रिगोर आह! ** छद्म कोड ** ___pseudocode___ _pseudocode_। – Neal

1

मैं दो अलग-अलग विकल्पों के बारे में सोच सकता हूं। पहले एक काफी होगा क्या @Neal पहले से ही सुझाव दिया है, लेकिन असली सी ++ कोड सहित:

struct Angle { 
    float heading; 
    float elevation; 
    float bank; 

    float& yaw() { return heading; } 
    float& pitch() { return elevation; } 
    float& roll() { return bank; } 

    const float& yaw() const { return heading; } 
    const float& pitch() const { return elevation; } 
    const float& roll() const { return bank; } 
}; 

तरीकों का पहला सेट गैर स्थिरांक संदर्भ देता है, तो यह वास्तव में इन के माध्यम से struct के गुणों को संशोधित करने के लिए संभव है तरीकों। उदाहरण के लिए:

Angle a{60, 45, 0}; 
a.roll() = 15; 

दूसरे सेट जब आप एक कोण करने के लिए एक निरंतर संदर्भ है और तुम सिर्फ struct में मूल्यों में पढ़ना चाहते हैं प्रयोग किया जाता है। उदाहरण के लिए:

void print_yaw(const Angle& a) { 
    std::cout << "yaw=" << a.yaw() << std::endl; 
} 

मैंने जीसीसी द्वारा उत्पन्न असेंबली कोड की जांच की है। दोनों सीधे स्ट्रक्चर विशेषता (उदा।, a.heading) का उपयोग करते हुए और उपनाम विधि (उदा।, a.yaw()) का उपयोग करके एक ही असेंबली कोड उत्पन्न करते हैं, इसलिए आप उपनाम विधि का उपयोग करने के लिए कोई दंड नहीं देते हैं।

दूसरा तरीका मैं सोच सकता हूं कि एक पूरी तरह से अलग दृष्टिकोण का उपयोग करना होगा। कुछ ऐसा:

enum Accessors { HEADING=0, ELEVATION, BANK }; 
enum AliasedAccessors { YAW=0, PITCH, ROLL }; 
typedef float Angle[3]; 

Angle a{60, 45, 0}; 
std::cout << a[HEADING] << " must be equal to " << a[YAW] << std::endl;