2016-01-03 9 views
7

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

union NextGen { 
    std::shared_ptr<TreeRecord> Child = nullptr; 
    std::vector<std::shared_ptr<TreeRecord>> Children; 
}; 

मेरे वर्तमान उपयोग:

void TreeRecord::AddChild(const std::shared_ptr<TreeRecord>& NewChild) { 
    if(_childCount == 0) { 
     _nextGeneration.Child = NewChild; 
     _childCount++; 
    } else if(_childCount == 1) { 
     //This is not clear to me: 
     //Do I have to set Child to nullptr first? 
     //Do I need to clear the Children vecor? 
     //Or will it work like this? 
     _nextGeneration.Children.push_back(_nextGeneration.Child); 
     _nextGeneration.Children.push_back(NewChild); 
     _childCount++; 
    } else { 
     _nextGeneration.Children.push_back(NewChild); 
     _childCount++; 
    } 
} 

नए सिरे से कार्यान्वयन (कोशिश):

typedef std::shared_ptr<TreeRecord> singlechild_type; 
typedef std::vector<std::shared_ptr<TreeRecord>> children_type; 



union { 
    singlechild_type _child; 
    children_type _children; 
}; 



void TreeRecord::AddChild(const singlechild_type& NewChild) { 
    if(_childCount == 0) { 
     _child = NewChild; 
     _childCount = 1; 

    } else if(_childCount == 1) { 
     singlechild_type currentChild = _child; //Copy pointer 
     _child.~singlechild_type(); //Destruct old union member 
     new (&_children) children_type(); //Construct new union member 
     _children.push_back(currentChild); //Add old child to vector 
     _children.push_back(NewChild); //Add new child to vector 
     _childCount = 2; 

    } else { 
     _children.push_back(NewChild); 
     _childCount++; 
    } 
} 

उत्तर

2

आप एक C++11 अनुरूप संकलक की जरूरत है। union -s के बारे में पढ़ें।

सामान्य रूप से, आपको स्पष्ट रूप से पुराने संघ के सदस्य के विनाशक और फिर नए संघ के सदस्य के निर्माता को कॉल करने की आवश्यकता है। असल में, आप बेहतर tagged unions होगा, वास्तविक union अनाम और कुछ वर्ग के सदस्य होने के साथ:

class TreeRecord; 

class TreeRecord { 
    bool hassinglechild; 
    typedef std::shared_ptr<TreeRecord> singlechild_type; 
    typedef std::vector<std::shared_ptr<TreeRecord>> children_type; 
    union { 
    singlechild_type child; // when hassinglechild is true 
    children_type children; // when hassinglechild is false 
    } 
    TreeRecord() : hassinglechild(true), child(nullptr) {}; 
    void set_child(TreeRecord&ch) { 
    if (!hassinglechild) { 
     children.~children_type(); 
     hassinglechild = true; 
     new (&child) singlechild_type(nullptr); 
    }; 
    child = ch; 
    } 
    /// other constructors and destructors skipped 
} 

सूचना जिन्हें मैंने स्पष्ट रूप नाशक ~children_type() बोल रहा हूँ तो मैं प्लेसमेंट का उपयोग कर रहा newको स्पष्ट रूप से कॉल child के लिए निर्माता।

rule of five का पालन करना न भूलें।

भी boost::variant

BTW अपने कोड का सुझाव है कि आप मामले को अलग है जब आप एक child और मामला है आप children के एक एक तत्व वेक्टर है जब देखें। क्या वह स्वैच्छिक और सार्थक है?

पीएस। कुछ भाषाओं में, विशेष रूप से ओकम्ल, टैग किए गए यूनियन (ए.के.ए. योग प्रकार) सी ++ 11 की तुलना में परिभाषित और कार्यान्वित करने के लिए काफी आसान हैं .... algebraic data types की विकिपीडिया देखें।

+0

इसके बारे में भी सोचा नहीं था! "सामान्य में" –

+0

का आपका क्या मतलब है यह सही जवाब है, लेकिन यदि आप विस्तृत करते हैं तो यह अच्छा होगा। – mostruash

+0

मेरे पास एक elem वेक्टर नहीं होगा। मैं या तो 0 या 1 elem के लिए चाइल्ड का उपयोग करता हूं और मैं 1 से अधिक elems के लिए वेक्टर पर स्विच करता हूं या मैंने गलती की है ...? (मैं अभी भी आपका कोड पढ़ रहा हूं) और मैं एक टैग किए गए यूनियन का उपयोग कर रहा हूं, सिर्फ बुलियन पहचानकर्ता के साथ नहीं बल्कि "size_t _childCount" के साथ, जो 0 या 1 है जब बच्चा मधुमक्खी का उपयोग कर रहा है। –

1

नोट, union के एक से अधिक तत्वों का उपयोग करके अनिश्चित रूप से अपरिभाषित व्यवहार का आह्वान करता है, उदा।

_nextGeneration.Children.push_back(_nextGeneration.Child); 

जैसा कि @ बेसिलस्टारनकेविच का उल्लेख है, एक तरीका यह है कि यह एक टैग किया गया संघ है।

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