2015-03-29 9 views
6

मैं प्रकार std::atomic<int> के एक सदस्य चर _atomicVar के साथ एक class A है संदर्भित करने के लिए प्रयास करते हैं।
त्रुटि C2280: किसी हटाए समारोह (परमाणु <int>)

#include <atomic> 

class A 
{ 
public: 
    A(); 
    ~A(); 

private: 
    std::atomic<int> _atomicVar; 
}; 

अगर मैं इस परियोजना मैं निम्नलिखित त्रुटि मिलती है निर्माण:

error C2280: 'std::atomic<int>::atomic(const std::atomic<int> &)' : attempting to reference a deleted function 

मैं मुख्य रूप से एक सी # डेवलपर हूं तो मैं सी के हर विस्तार ++ (अभी तक) पता नहीं है। मुझे नहीं पता कि मैं atomic<int> की कॉपी c'tor का उपयोग कहां करता हूं।
मैं भी _atomicVar प्रारंभ करने की कोशिश की:

std::atomic<int> _atomicVar { 0 }; 

... लेकिन बात नहीं बनी।
मुझे उम्मीद है कि _atomicVar (स्पष्ट प्रारंभिकरण के बिना) int के डिफ़ॉल्ट मान के साथ आरंभ किया जाएगा।
क्या आप मुझे बता सकते हैं कि यह त्रुटि क्यों होती है?

+0

आप विजुअल स्टूडियो का उपयोग कर रहे प्रतीत होते हैं। कौन सा संस्करण? कोड की आपको किस पंक्ति पर त्रुटि मिलती है? –

+2

क्या यह आपका पूरा कोड है? शायद आप 'ए' ऑब्जेक्ट्स की प्रतिलिपि बना रहे हैं? हो सकता है कि आप एक कंटेनर का उपयोग करें जिसके लिए 'CopyConstructible' तत्वों की आवश्यकता है? – zch

+2

बस कॉपी कन्स्ट्रक्टर को परिभाषित नहीं करने के लिए पर्याप्त कारण है।जब आप प्रकारों को परिभाषित करते हैं, जिनमें 'परमाणु' सदस्य होते हैं, तो आपको सभी अंतर्निहित संचालन के लिए स्पष्ट अर्थात् परिभाषित करना होगा, जिसे संकलक द्वारा निष्पादित या डाला जा सकता है। –

उत्तर

14

ऐसा इसलिए है क्योंकि std::atomic की कॉपी कन्स्ट्रक्टर हटा दी गई है।

this documentation page देखें।

चूंकि आप A के लिए स्पष्ट प्रतिलिपि निर्माता को परिभाषित नहीं करते हैं, इसलिए संकलक डिफ़ॉल्ट उत्पन्न करता है, जो सभी सदस्यों के लिए कॉपी कन्स्ट्रक्टर कहता है (जिसे std::atomic के लिए अनुमति नहीं है)।

समाधान:

class A 
{ 
public: 
    A(); 
    A(const A& origin); // add this line 
    ~A(); 
private: 
    std::atomic<int> _atomicVar; 
}; 

A::A(const A& origin) 
: _atomicVar(0) //zero-initialize _atomicVar 
{ 
} 

संपादित

आपको आश्चर्य है, तो क्यों atomic प्रकार copyable नहीं हैं, आप this question, विशेष रूप से स्वीकार किए जाते हैं जवाब को पढ़ने के लिए चाहते हो सकता है। आप std::atomic का मूल्य की प्रतिलिपि बनाना चाहते हैं, तो आप यह कर सकते हैं:

A::A(const A& origin) 
: _atomicVar(origin._atomicVar.load()) 
{ 
} 

लेकिन ध्यान रखें, कि इस आपरेशन में ही एक परमाणु एक (और, सबसे लॉजिक्स के लिए, व्यर्थ) नहीं होगा।

इसके अलावा, आप स्पष्ट असाइनमेंट ऑपरेटर को परिभाषित करना भी चाह सकते हैं (Rule of Three के बारे में याद रखें)।

अपने कार्यक्रम के समुचित व्यवहार के लिए सबसे अच्छा विकल्प इन दोनों तरीकों को हटाने की जाएगी:

class A 
{ 
public: 
    A(); 
    A(const A&) = delete; 
    ~A(); 

    A& operator=(const A&) = delete; 

private: 
    std::atomic<int> _atomicVar; 
}; 

अपने संकलक इस का समर्थन नहीं करता (जैसे VC12 से पहले किसी भी वीसी), उन्हें निजी रूप में घोषित करने और नहीं है एक शरीर प्रदान करें:

class A 
{ 
public: 
    A(); 
    ~A(); 

private: 
    //do not define these two 
    A(const A&); 
    A& operator=(const A&); 

private: 
    std::atomic<int> _atomicVar; 
}; 
+3

एहम मैं यह नहीं करूँगा - अब 'ए' की कॉपी सेमेन्टिक्स टूटा हुआ है। मैं इसके बजाय 'ए' की कॉपी कन्स्ट्रक्टर को हटा दूंगा। –

+1

हाँ, आप सही हैं। जब आप इसे लिखते थे तो मैं पहले ही अपना जवाब अपडेट कर रहा था। –

+0

धन्यवाद @MateuszGrzejek ने वास्तव में मेरी मदद की, मेरे पास एक कक्षा है जिसे एक साझा_प्टर का उपयोग करके तत्काल किया गया था, और कक्षा ने आगे की घोषणा के लिए एक अद्वितीय_ptr आयोजित किया था, मुझे पहली बार त्रुटि मिलने पर त्रुटि नहीं मिली क्योंकि मैंने डिफ़ॉल्ट प्रदान किया था विनाशक को एक अद्वितीय_ptr में आगे की घोषणा का उपयोग करने के लिए आवश्यक है, इसे पढ़ने के बाद और कक्षा में एक अतिरिक्त प्रतिलिपि बनाने वाला बनाने के लिए, अनन्य_प्टर नलप्टर को सही कन्स्ट्रक्टर कहने तक सेट करने के लिए, मेरा कोड काम करता है, इसलिए एक अच्छे उत्तर के लिए धन्यवाद बहुत मदद मिली (= – daniel

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