2010-07-17 8 views
11

यदि हां, तो क्यों? यह मूल्य प्रकार की कॉपी कन्स्ट्रक्टर का उपयोग क्यों नहीं करता है?क्या std :: vector push_back तत्वों के लिए अपने मान प्रकार के असाइनमेंट ऑपरेटर का उपयोग करता है?

/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc: In member functio 
n `ClassWithoutAss& ClassWithoutAss::operator=(const ClassWithoutAss&)': 
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc:238: instantiate 
d from `void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterato 
r<typename _Alloc::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = 
ClassWithoutAss, _Alloc = std::allocator<ClassWithoutAss>]' 
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_vector.h:564: instantia 
ted from `void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = Class 
WithoutAss, _Alloc = std::allocator<ClassWithoutAss>]' 
main.cpp:13: instantiated from here 
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc:238: error: non-st 
atic const member `const int ClassWithoutAss::mem', can't use default assignment 
operator 

चल छ निम्नलिखित कोड पर ++ main.cpp:

मैं निम्नलिखित त्रुटि मिलती है

/* 
* ClassWithoutAss.h 
* 
*/ 

#ifndef CLASSWITHOUTASS_H_ 
#define CLASSWITHOUTASS_H_ 

class ClassWithoutAss 
{ 

public: 
    const int mem; 
    ClassWithoutAss(int mem):mem(mem){} 
    ClassWithoutAss(const ClassWithoutAss& tobeCopied):mem(tobeCopied.mem){} 
    ~ClassWithoutAss(){} 

}; 

#endif /* CLASSWITHOUTASS_H_ */ 

/* 
* main.cpp 
* 
*/ 

#include "ClassWithoutAss.h" 
#include <vector> 

int main() 
{ 
    std::vector<ClassWithoutAss> vec; 
    ClassWithoutAss classWithoutAss(1); 
    (vec.push_back)(classWithoutAss); 

    return 0; 
} 
+13

+1 केवल 'क्लासविथआउटएएसएस' के लिए। – GManNickG

+2

आप vec.push_back को ब्रैकेट क्यों करते हैं ... इससे कोई समस्या नहीं आती है लेकिन एक अनावश्यक लगता है ... – Goz

+1

क्या यह "गधे" जैसा "गधा" है? – sbi

उत्तर

13

सी ++ 03 मानक का कहना तत्वों कॉपी-constructible और copy- होना चाहिए एक मानक कंटेनर में इस्तेमाल करने के लिए असाइन करने योग्य। तो जो भी चाहें उसका उपयोग करने के लिए एक कार्यान्वयन मुक्त है।

सी ++ 0x में, इन आवश्यकताओं को प्रति-संचालन आधार पर रखा जाता है। (सामान्य रूप से, तत्वों को स्थानांतरित करने योग्य और स्थानांतरित करने योग्य होना चाहिए।)

आप जो चाहते हैं उसे प्राप्त करने के लिए, आपको shared_ptr (बूस्ट, टीआर 1, या सी ++ 0x से) जैसे स्मार्ट पॉइंटर का उपयोग करना चाहिए, और पूरी तरह से को निष्क्रिय कॉपी-क्षमता:

class ClassWithoutAss 
{ 
public: 
    const int mem; 

    ClassWithoutAss(int mem):mem(mem){} 
    // don't explicitly declare empty destructors 

private: 
    ClassWithoutAss(const ClassWithoutAss&); // not defined 
    ClassWithoutAss& operator=(const ClassWithoutAss&); // not defined 
}; 

typedef shared_ptr<ClassWithoutAss> ptr_type; 

std::vector<ptr_type> vec; 
vec.push_back(ptr_type(new ClassWithoutAss(1))); 

प्वाइंटर ठीक कॉपी किया जा सकता है, और स्मार्ट सूचक सुनिश्चित करता है आप रिसाव नहीं है। सी ++ 0x में आप std::unique_ptr के साथ यह सर्वोत्तम प्रदर्शन कर सकते हैं, जो चाल-अर्थशास्त्र का लाभ उठाते हैं। (आपको वास्तव में साझा अर्थशास्त्र की आवश्यकता नहीं है, लेकिन सी ++ 03 में यह सबसे आसान है क्योंकि यह खड़ा है।)

+0

मैं आपको विश्वास करता हूं, लेकिन क्या आप समझा सकते हैं कि क्यों अपने खुद के परिचालन को परिभाषित करने के बजाय पॉइंटर्स? तेज़ push_backs? तो मैं अपना समय परिभाषित परिचालन बर्बाद नहीं करता? मुझे सैमांतिक्स को स्थानांतरित/साझा करना होगा। धन्यवाद जीएमएन। मुझे आपकी मदद से केवल इन समस्याएं हैं। ;) – user383352

+0

@ ड्रेनमी: आपका क्या मतलब है? मैंने पॉइंटर्स का इस्तेमाल किया क्योंकि आप कंटेनर में अपनी कक्षा रखना चाहते हैं, लेकिन आप इसे सीधे नहीं कर सकते हैं। इसके ऊपर एक अमूर्त वर्ग की बजाय आपकी कक्षा के लिए एक सूचक है। (और लीक को रोकने के लिए स्मार्ट पॉइंटर्स।) – GManNickG

+0

लेकिन अगर मैं एक असाइनमेंट ऑपरेटर को सही तरीके से परिभाषित कर सकता हूं तो क्या मैं कर सकता हूं? तो मेरा प्रश्न दो डिज़ाइनों का समर्थक/विपक्ष है - बिना किसी असाइनमेंट/पॉइंटर्स का उपयोग, एक परिभाषित असाइनमेंट। दोनों विकल्प हैं क्योंकि मैं क्लासविथएएसएस लिख सकता हूं। – user383352

4

समस्या यह है कि एक कंटेनर में प्रकार असाइन करने योग्य होना चाहिए।

क्योंकि आप अपनी कक्षा के लिए असाइनमेंट ऑपरेटर को परिभाषित नहीं करते हैं तो संकलक आपके लिए एक उत्पन्न करेगा। डिफ़ॉल्ट असाइनमेंट ऑपरेटर इस तरह दिखेगा:

ClassWithoutAss& operator=(ClassWithoutAss const& rhs) 
{ 
    mem = copy.mem; 
    return *this; 
} 
// The compiler generated assignemtn operator will copy all members 
// using that members assignment operator. 

अधिकांश स्थितियों में यह काम करेगा। लेकिन सदस्य मेम एक कॉन्स है और इस प्रकार असाइन करने योग्य है। इसलिए संकलन विफल हो जाएगा जब यह असाइनमेंट ऑपरेटर उत्पन्न करने का प्रयास करता है।

+1

मैं 'Ass' के साथ कक्षाओं को प्राथमिकता देता हूं – Balk

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