2016-09-05 7 views
12

क्या कोई इस सी ++ संकलन त्रुटि की प्रकृति को समझा सकता है? मैं वैश्विक ऑपरेटरों को नए, हटाए जाने और उनके रूपों को ओवरलोड करने के बारे में सीख रहा हूं। मैंने coupleofarticlesonthesubject पढ़ा, लेकिन मुझे यह विशेष रूप से संबोधित करने वाला कोई नहीं मिला।क्यों सी ++ ऑपरेटर नए/डिलीट/वेरिएंट हेडर फाइलों में नहीं होना चाहिए?

कोड

foo.h:

#ifndef foo_h 
#define foo_h 

void* operator new(size_t); 
void* operator new[](size_t); 

void operator delete(void*); 
void operator delete[](void*); 

#endif // foo_h 

foo.cpp:

#include <foo.h> 
#include <iostream> 

void* operator new(size_t size) { return NULL; } 
void* operator new[](size_t size) { return NULL; } 

void operator delete(void* p) { } 
void operator delete[](void* p) { } 

संकलन त्रुटि

>g++ -g -std=c++14 -I./ -c foo.cpp -o foo.o 
In file included from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ext/new_allocator.h:33:0, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/x86_64-pc-cygwin/bits/c++allocator.h:33, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/allocator.h:46, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/string:41, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/locale_classes.h:40, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/ios_base.h:41, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ios:42, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ostream:38, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/iostream:39, 
       from foo.cpp:2: 
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/new:116:41: error: declaration of ‘void operator delete(void*) noexcept’ has a different exception specifier 
    __attribute__((__externally_visible__)); 
             ^
In file included from foo.cpp:1:0: 
./foo.h:8:6: error: from previous declaration ‘void operator delete(void*)’ 
void operator delete(void* p); 
    ^
In file included from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ext/new_allocator.h:33:0, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/x86_64-pc-cygwin/bits/c++allocator.h:33, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/allocator.h:46, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/string:41, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/locale_classes.h:40, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/ios_base.h:41, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ios:42, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ostream:38, 
       from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/iostream:39, 
       from foo.cpp:2: 
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/new:118:41: error: declaration of ‘void operator delete [](void*) noexcept’ has a different exception specifier 
    __attribute__((__externally_visible__)); 
             ^
In file included from foo.cpp:1:0: 
./foo.h:9:6: error: from previous declaration ‘void operator delete [](void*)’ 
void operator delete[](void* p); 
    ^

इस मुद्दे के बारे में कुछ विषमताएं कि मुझे लगता है कि प्रासंगिक हैं:

  • अगर मैं foo.cpp में #include <iostream> बाहर टिप्पणी, संकलन सफल होता है
  • अगर मैं foo.h में समारोह घोषणाओं बाहर टिप्पणी, और केवल उनकी परिभाषा रखने के लिए, foo.cpp में (और #include <iostream> भी रखते हुए), संकलन सफल होता है।

मुझे कुछ अस्पष्ट संदेह हैं; शायद answerers उनके जवाब के माध्यम से की पुष्टि करेगा:

  • त्रुटि बनाता है एक exception specifier का उल्लेख तो मैं इन ऑपरेटरों के किसी भी अधिभावी द्वारा शायद सोचा, मैं अपने भाई बहन की पूरी सूट को ओवरराइड करने के लिए बाध्य कर रहा हूँ। हालांकि, operator delete(void*, const std::nothrow_t&) घोषणा और परिभाषा जोड़ना संकलन त्रुटि को नहीं बदला है। मुझे यह भी नहीं लगता कि यह सच होना चाहिए कि इनमें से किसी भी ऑपरेटरों को ओवरराइड करना कोडर को उन सभी को लागू करने के लिए बाध्य करता है, लेकिन क्या मैं उस पर गलत हूं?
  • मैंने स्टैक ओवरफ्लो के बाहर एक लेख पढ़ा है जिसमें यह बताया गया है कि इन ऑपरेटरों को केवल एक "अनुवाद इकाई" में शामिल किया जाना चाहिए और इसलिए हेडर फ़ाइलों में नहीं होना चाहिए। मुझे समझ में नहीं आता कि एक अनुवाद इकाई क्या है, और उस लेख ने यह नहीं बताया कि यह क्या है। यदि यह इस समस्या से संबंधित है, तो कृपया बताएं कि "अनुवाद इकाई" क्या है और क्यों इसे हेडर फ़ाइल से फ़ंक्शन घोषणाओं को बहिष्कृत करने की आवश्यकता है - यह मेरे सभी पूर्व C++ कोडिंग अनुभव के विपरीत लगता है।

किसी भी अंतर्दृष्टि के लिए धन्यवाद।

उत्तर

5

जो समस्या आप देख रहे हैं वह निम्नलिखित घोषणाओं में अंतर के कारण है। उन्हें अपने में घोषित करने के बजाय

void operator delete(void*); 
void operator delete [](void*); 

: जब आप के रूप में उन्हें घोषित

void operator delete(void*) noexcept; 
void operator delete [](void*) noexcept; 

:

पुस्तकालय के रूप में operator delete कार्यों की घोषणा की।ज फ़ाइल, आप

#include <new> 

लुक अनुभाग 18.6 गतिशील स्मृति प्रबंधन सी ++ 11 मानक के आप इस विषय पर अधिक जानकारी के लिए यह करने के लिए उपयोग किया है, तो उपयोग करना चाहिए।

एक अनुवाद इकाई आमतौर पर एक .cpp फ़ाइल होती है। आगे पढ़ने: What is a "translation unit" in C++

+1

आपके उत्तर ने मुझे एहसास दिलाया कि संकलक त्रुटि वास्तव में मुझे बता रही थी कि समस्या क्या थी। इसे और अधिक जांचने के लिए मेरा बुरा, लेकिन धन्यवाद; आपके जवाब ने मुझे अंतर को पुल करने में मदद की। – StoneThrow

+0

यह अजीब बात है, क्योंकि मैं वही त्रुटि पुन: उत्पन्न करने में सक्षम नहीं हूं, और मैंने सटीक कोड की प्रतिलिपि बनाई है, जिसे प्रश्न में पोस्ट किया गया था। अगर यह वास्तव में समस्या है, तो मुझे त्रुटि क्यों नहीं मिल रही है? बीटीडब्ल्यू, मैं वीएस 2015 का उपयोग कर रहा हूं। –

+0

@ मुहम्मद अहमद, मुझे नहीं पता कि आपको कोई त्रुटि क्यों नहीं मिल रही है। यह खोज के लायक है। –

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