2012-02-29 13 views
10

सी ++ 03 में अनावश्यक प्रतियों की समस्या थी जो स्पष्ट रूप से हो सकती थीं। इस उद्देश्य के लिए, सी ++ 11 ने rvalue references और move semantics पेश किया। अब मेरा सवाल यह है कि, क्या यह अनावश्यक प्रतिलिपि समस्या सी # और जावा जैसी भाषाओं में भी मौजूद है या क्या यह केवल सी ++ समस्या थी? दूसरे शब्दों में, rvalue references सी ++ 11 को सी # या जावा की तुलना में और भी अधिक कुशल बनाता है?सी ++ रावल्यू संदर्भ और सैमांतिक्स

जहां तक ​​सी # संबंधित (इसमें ऑपरेटर ओवरलोडिंग की अनुमति है), मान लें कि हमारे पास गणितीय वेक्टर क्लास है, और हम इसका उपयोग इस तरह करते हैं।

vector_a = vector_b + vector_c; 

संकलक निश्चित रूप से कुछ अस्थायी वस्तु को vector_b + vector_c बदल सकते हैं (यह vector_tmp फोन की सुविधा देता है)।

अब मुझे नहीं लगता कि सी # vector_tmp के रूप में इस तरह के एक अस्थायी rvalue या vector_b के रूप में एक एक lvalue इस तरह के बीच अंतर कर सकते हैं, तो हम, वैसे भी vector_a डेटा कॉपी करना होगा जो आसानी से rvalue references और move semantics का उपयोग करके बचा जा सकता है सी ++ 11 में।

+3

कि असंबंधित –

उत्तर

5

हां अनावश्यक प्रतिलिपि सी # और जावा में हैं।

क्या रैवल्यू संदर्भ C++ 11 को सी # या जावा की तुलना में और भी अधिक कुशल बनाता है?

उत्तर हाँ है। :)

+3

हैं जब आप मतलब है कि यह जावा में होता है भाषा टैग का उपयोग नहीं करते हैं? कृपया एक उदाहरण प्रदान करें। यह क्लोन इत्यादि को कॉल करने वाले विशिष्ट कार्यान्वयन में हो सकता है, लेकिन यह बिंदु के बगल में प्रतीत होता है। जावा में डिफ़ॉल्ट प्रतिलिपि बनाने वाले और निहित प्रतियां नहीं होती हैं क्योंकि यह डिफ़ॉल्ट रूप से ऑब्जेक्ट्स के संदर्भ पारित करती है (वास्तव में मूल्य से)। –

+0

सेबेस्टियन ओल्सन: जाहिर है कि रावल्यू संदर्भों में कॉपी कन्स्ट्रक्टर के साथ कुछ लेना देना नहीं है। इसे समशीतोष्ण राजस्व के साथ करना है। सी # कैसे संभालता है? मेरा मतलब है कि यह अस्थायी वस्तुओं से प्रतिलिपि कैसे संभालता है। उदाहरण के लिए आपके पास ओवरलोडेड ऑपरेशंस वाले क्लास हैं और आपके पास यह अभिव्यक्ति ए = बी + सी + डी है। सी ++ और सी # इसे अलग तरीके से कैसे संभालता है। सी ++ कार्यान्वयन उपयोग संदर्भ मानें। – MetallicPriest

+0

यह एक अनावश्यक विनाश निर्माण के बारे में है। मेरा मुद्दा यह था कि जावा ऑब्जेक्ट सृजन का तरीका सी ++ करता है। मैं सी # में ऑपरेटर ओवरलोडिंग के बारे में जवाब देने की हिम्मत नहीं करता क्योंकि यह विशेषज्ञता का मेरा क्षेत्र नहीं है। –

4

क्योंकि जावा और सी # संदर्भ संदर्भ अर्थशास्त्र में कक्षाएं, उन भाषाओं में वस्तुओं की कोई भी निहित प्रतियां कभी नहीं होती हैं। समस्या को सेमेन्टिक्स हल करने में समस्या नहीं होती है और जावा और सी # में कभी अस्तित्व में नहीं है।

+1

सी ++ संदर्भ अर्थशास्त्र का भी उपयोग कर सकते हैं। असल में, कॉपी कन्स्ट्रक्टर लगभग हमेशा लिखे जाते हैं जैसे कि वे निरंतर संदर्भ लेते हैं। तो समस्या संदर्भों के साथ कुछ भी प्रतीत नहीं होती है। – MetallicPriest

+10

"संदर्भ द्वारा उत्तीर्ण" और "संदर्भ अर्थशास्त्र" दो अलग-अलग चीजें हैं। – fredoverflow

+0

क्या अंतर है? – MetallicPriest

7

सी # और जावा में कक्षा संदर्भों में सी ++ में shared_ptr एस के कुछ गुण हैं। हालांकि, रैवल्यू संदर्भ और स्थानांतरित सैमसंगिक्स अस्थायी मूल्य प्रकारों से अधिक संबंधित हैं, लेकिन सी # में मान प्रकार सी ++ मूल्य प्रकारों की तुलना में काफी गैर-लचीला हैं, और मेरे अपने सी # अनुभव से, आप वर्गों के साथ समाप्त होंगे, अधिकतर structs नहीं समय की।

तो मेरी धारणा यह है कि न तो जावा और न ही सी # उन नई सी ++ सुविधाओं से बहुत लाभान्वित होंगे, जिससे कोड सुरक्षित धारणा करता है कि कुछ अस्थायी है या नहीं, प्रतिलिपि बनाने की बजाय यह सामग्री को चुरा लेती है।

1

मुझे लगता है कि यह जावा में हो सकता है। नीचे जोड़ें और add_to ऑपरेशन देखें। मैट्रिक्स ऐड ऑपरेशन के परिणाम को पकड़ने के लिए परिणाम ऑब्जेक्ट बनाता है, जबकि add_to केवल rhs को जोड़ता है।

class Matrix { 
    public static final int w = 2; 
    public static final int h = 2; 

    public float [] data; 

    Matrix(float v) 
    { 
     data = new float[w*h]; 
     for(int i=0; i<w*h; ++i) 
      { data[i] = v; } 
    } 

    // Creates a new Matrix by adding this and rhs 
    public Matrix add(Matrix rhs) 
    { 
     Main result = new Main(0.0f); 
     for(int i=0; i<w*h; ++i) 
      { result.data[i] = this.data[i] + rhs.data[i]; } 

     return result; 
    } 

    // Just adds the values in rhs to this 
    public Main add_to(Main rhs) 
    { 
     for(int i=0; i<w*h; ++i) 
      { this.data[i] += rhs.data[i]; } 
     return this;  
    } 

    public static void main(String [] args) 
    { 
     Matrix m = new Matrix(0.0f); 
     Matrix n = new Matrix(1.0f); 
     Matrix o = new Matrix(1.0f); 

     // Chaining these ops would modify m 
     // Matrix result = m.add_to(n).subtract_from(o);  
     m.add_to(n);   // Adds n to m 
     m.subtract_from(o); // Subtract o from n 

     // Can chain ops without modifying m, 
     // but temps created to hold results from each step 
     Matrix result = m.add(n).subtract(o); 
    } 
} 

इस प्रकार, मुझे लगता है कि यह इस बात पर निर्भर करता है कि आप अपनी कक्षाओं के साथ उपयोगकर्ता को किस तरह की कार्यक्षमता प्रदान कर रहे हैं।

0

समस्या बहुत अधिक आती है। कोई भी मैं किसी ऑब्जेक्ट की एक अनूठी प्रतिलिपि रखना चाहता हूं जिसे कोई और संशोधित नहीं कर सकता है। मैं उसको कैसे करू?

  1. कोई भी वस्तु मुझे किसी भी वस्तु की गहरी प्रति बनाएं? यह काम करेगा, लेकिन यह कुशल नहीं है।
  2. लोगों से मुझे एक नई वस्तु देने और प्रतिलिपि रखने के लिए कहें? यदि आप बहादुर हैं तो यह तेज़ है। बग ऑब्जेक्ट घंटों को बाद में संशोधित कोड के पूरी तरह से असंबंधित टुकड़े से आ सकते हैं।
  3. सी ++ शैली: इनपुट से सभी वस्तुओं को अपनी नई वस्तु में ले जाएं। यदि कॉलर गलती से ऑब्जेक्ट का फिर से उपयोग करने का प्रयास करता है, तो वह तुरंत समस्या को देखेगा।
  4. कभी-कभी सी # केवल पढ़ने वाला संग्रह मदद कर सकता है। लेकिन मेरे अनुभवों में आमतौर पर दर्द होता है।

यहाँ मैं किस बारे में बात कर रहा हूँ है:

class LongLivedObject 
{ 
    private Dictionary <string, string> _settings; 
    public LongLivedObject(Dictionary <string, string> settings) 
    { // In C# this always duplicates the data structure and takes O(n) time. 
     // C++ will automatically try to decide if it could do a swap instead. 
     // C++ always lets you explicitly say you want to do the swap. 
     _settings = new Dictionary <string, string>(settings); 
    } 
} 

यह सवाल और Clojure के दिल अन्य कार्यात्मक भाषाओं में है!

संक्षेप में, हाँ, मैं अक्सर चाहता हूं कि सी # + 11 शैली डेटा संरचनाएं और संचालन सी # में हों।

0

आप चाल semantics अनुकरण करने की कोशिश कर सकते हैं। व्यापार-विचार फिलिप के उदाहरण में उदाहरण के लिए यदि आप कस्टम Dictionary के बजाय MovableDictionary पारित कर सकते हैं:

public class MovableDictionary<K, V> // : IDictionary<K, V>, IReadOnlyDictionary<K, V>... 
{ 
    private Dictionary<K, V> _map; 

    // Implement all Dictionary<T>'s methods by calling Map's ones. 

    public Dictionary<K, V> Move() 
    { 
     var result = Map; 
     _map = null; 
     return result; 
    } 

    private Dictionary<K, V> Map 
    { 
     get 
     { 
      if (_map == null) 
       _map = new Dictionary<K, V>(); 

      return _map; 
     } 
    } 
} 
संबंधित मुद्दे