2013-04-09 7 views
7

मुझे मेरे कन्स्ट्रक्टर के साथ कुछ समस्या है। मेरी हेडर फाइल में मैं घोषणा:सी ++ त्रुटि: 'char *' के असाइनमेंट में असंगत प्रकार 'char [2]

char short_name_[2]; 
  • और अन्य चर

मेरी निर्माता में:

Territory(std::string name, char short_name[2], Player* owner, char units); 
void setShortName(char* short_name); 
inline const char (&getShortName() const)[2] { return short_name_; } 

मेरी cpp फ़ाइल में:

Territory::Territory(std::string name, char short_name[2], Player* owner, 
        char units) : name_(name), short_name_(short_name), 
        owner_(owner), units_(units) 
{ } 

मेरे त्रुटि:

Territory.cpp: In constructor ‘Territory::Territory(std::string, char*, Player*, char)’: Territory.cpp:15:33: error: incompatible types in assignment of ‘char*’ to ‘char [2]’

मैं पहले से ही पता लगा कि char[2] <=> char* लेकिन मैं कैसे मेरे निर्माता के बारे में इस संभालने के लिए और प्राप्त करने के लिए/setters यकीन नहीं है।

+1

'मुझे पहले से ही पता चला है कि char [2] <=> char * वास्तव में नहीं। – Rapptz

+0

लेकिन मैंने सोचा कि सी ++ कंपाइलर char [2] char * के बराबर है? मुझे वास्तव में कोई जानकारी नहीं है कि इस कन्स्ट्रक्टर और गेटर्स को गड़बड़ कैसे करें ... – vicR

+1

Arrays और पॉइंटर्स * बहुत * अलग-अलग चीजें हैं। [Comp.lang.c FAQ] (http://www.c-faq.com/) की सेक्शन 6 पढ़ें; इस क्षेत्र में नियम अनिवार्य रूप से सी और सी ++ के लिए समान हैं। –

उत्तर

12

सी ++ में कच्चे सरणी खतरनाक और खतरे से भरे हुए हैं। यही कारण है कि जब तक आपके पास std::vector या std::array का उपयोग करने के लिए बहुत अच्छा कारण नहीं है।

सबसे पहले, जैसा कि अन्य ने कहा है, char[2]char*, या कम से कम आमतौर पर नहीं है। char[2]char और char* का आकार 2 सरणी char पर एक सूचक है। वे अकसर उलझन में आ जाते हैं क्योंकि जब भी उन्हें आवश्यकता होती है तो पहले तत्वों के लिए एरे एक पॉइंटर को क्षय कर देंगे। तो यह काम करता है:

char foo[2]; 
char* bar = foo; 

लेकिन रिवर्स नहीं करता है:

const char* bar = "hello"; 
const char foo[6] = bar; // ERROR 

भ्रम, को जोड़ना जब फ़ंक्शन पैरामीटर घोषणा करते हुए char[]char* के बराबर है। तो आपके कन्स्ट्रक्टर में पैरामीटर char short_name[2] वास्तव में char* short_name है।

सरणी का एक और क्विर्क यह है कि उन्हें अन्य प्रकारों की तरह कॉपी नहीं किया जा सकता है (यह एक स्पष्टीकरण है कि फ़ंक्शन पैरामीटर में सरणी को पॉइंटर्स के रूप में क्यों माना जाता है)।उदाहरण के लिए मैं कुछ इस तरह से काम नहीं कर सकते हैं:

char foo[2] = {'a', 'b'}; 
char bar[2] = foo; 

इसके बजाय मैं foo के तत्वों से अधिक पुनरावृति और bar में उन्हें कॉपी, या कुछ समारोह जो करता है का उपयोग करना होगा के लिए मुझे इस तरह के std::copy के रूप में:

char foo[2] = {'a', 'b'}; 
char bar[2]; 
// std::begin and std::end are only available in C++11 
std::copy(std::begin(foo), std::end(foo), std::begin(bar)); 

तो अपने निर्माता में आप मैन्युअल रूप से short_name_ में short_name के तत्वों की नकल करने के लिए है:

Territory::Territory(std::string name, char* short_name, Player* owner, 
        char units) : name_(name), owner_(owner), units_(units) 
{ 
    // Note that std::begin and std::end can *not* be used on pointers. 
    std::copy(short_name, short_name + 2, std::begin(short_name)); 
} 

जैसा कि आप देख सकते हैं कि यह बहुत ही कष्टप्रद है, इसलिए जब तक आपके पास बहुत अच्छा कारण न हो, तो आपको कच्चे सरणी के बजाय std::vector का उपयोग करना चाहिए (या इस मामले में शायद std::string)।

2

जब कोई फ़ंक्शन तर्क के रूप में सरणी चाहता है, तो उसे इसके बजाय सरणी के पहले तत्व में पॉइंटर मिलता है। इस सूचक का उपयोग किसी सरणी को प्रारंभ करने के लिए नहीं किया जा सकता है, क्योंकि यह एक सूचक है, एक सरणी नहीं है।

आप कार्यों कि संदर्भ तर्कों के रूप सरणियों को स्वीकार लिख सकते हैं:

void i_dont_accept_pointers(const char (array&)[2]) {} 

समस्या है यहाँ, कि इस सरणी संदर्भ एक और सरणी को प्रारंभ करने के लिए इस्तेमाल नहीं किया जा सकता।

class Foo { 
    char vars[2]; 
    Foo(const char (args&)[2]) 
    : vars(args) // This will not work 
    {} 
}; 

सी ++ 11 शुरू की std::array इस और सरणियों की अन्य समस्याओं eliminiate करने के लिए। पुराने संस्करणों में, आपको सरणी तत्वों के माध्यम से पुनरावृत्त करना होगा और उन्हें अलग-अलग कॉपी करना होगा या std::copy का उपयोग करना होगा।

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