2012-04-27 9 views
29

मेरे पास दो वर्ग, मेष और मेशलिस्ट हैं। मैं चाहता हूं कि मेशलिस्ट के पास ऐसा कार्य हो जो मेष के निजी सदस्यों को बदल सके। लेकिन यह संकलित नहीं होगा और मुझे नहीं पता क्यों। मेरा कोड यहाँ है।सी ++ मुझे दोस्त बनाने नहीं देगा

Mesh.h

#ifndef _MESH_H 
#define _MESH_H 

#include "MeshList.h" 
#include <iostream> 

class Mesh 
{ 
private: 
    unsigned int vboHandle_; 
    friend void MeshList::UpdateVBOHandle(); 
public: 
    inline void Out() {std::cout << vboHandle_;} 
}; 
#endif 

Mesh.cpp

#include "Mesh.h" 

MeshList.h

#ifndef _MESH_LIST_H 
#define _MESH_LIST_H 

#include "Mesh.h" 


class MeshList 
{ 

public: 
    Mesh *mesh; //Line 11 Error 
    void UpdateVBOHandle(); 
}; 
#endif 

MeshList.cpp

#include "MeshList.h" 

void MeshList::UpdateVBOHandle() 
{ 
    *mesh->vboHandle_ = 4; 
} 

मैं इन त्रुटियों को मिलता है:

MeshList.h (लाइन 11)

  • त्रुटि C2143: सिंटेक्स त्रुटि: लापता ';' '*'
  • त्रुटि C4430: गायब प्रकार विनिर्देशक - int माना जाता है। नोट: सी ++ समर्थन डिफ़ॉल्ट-int
  • त्रुटि C4430: गायब प्रकार विनिर्देशक - int माना जाता है। नोट: सी ++ नहीं समर्थन डिफ़ॉल्ट-पूर्णांक

  • mesh.h (11): त्रुटि C2653: 'MeshList': नहीं एक वर्ग या नाम स्थान नाम है

  • meshlist.cpp (5): त्रुटि C2248 : 'जाल :: vboHandle_': उपयोग कर सकते हैं नहीं निजी सदस्य कक्षा में 'जाल'
  • mesh.h घोषित (10): 'जाल :: vboHandle_'
  • mesh.h की घोषणा को देखने के (8): घोषणा देखना 'मेष'
  • meshlist.cpp (5): त्रुटि C2100: अवैध संकेत
+38

आपको और अधिक जानकारी प्राप्त करने की आवश्यकता है। अकेले शीर्षक के लिए –

+32

+1। –

+5

शीर्षक के लिए '# शामिल" MeshList.h "' – chris

उत्तर

6

चक्रीय निर्भरता अन्य उत्तर में विस्तार से बताया जाता है ...

यहाँ समाधान आता है:

MeshList.h में:

  • आगे घोषणा class Mesh; के साथ बदलें #include "Mesh.h" (आप डॉन यहां शामिल करने की आवश्यकता नहीं है, क्योंकि आप केवल मेष को पॉइंटर घोषित करते हैं)

MeshList.cpp में:

:

  • अपने शामिल करने के लिए #include "Mesh.h" जोड़ने (आप, घोषणा की जरूरत है क्योंकि आप जाल का उपयोग)

पिछले संकलन त्रुटि, आप का उल्लेख किया एक और समस्या है

*mesh->vboHandle_ = 4; 

mesh एक सूचक है। आपका कोड सदस्य vboHandle_ का चयन करता है और इसे अस्वीकार करने का प्रयास करता है (जो विफल रहता है)। मुझे लगता है कि आपका मतलब है:

mesh->vboHandle_ = 4; // <-- no leading asterisk 
+0

डेविड की टिप्पणी के अनुसार उत्तर तय किया। – Stephan

9

जब आप संकलन Mesh.cpp, यह Mesh.h भी शामिल है, जो MeshList.h भी शामिल है, जो Mesh.h शामिल करने के लिए शुरू होता है, लेकिन जल्दी बंद हो जाता है क्योंकि _MESH_H अब परिभाषित किया गया है। फिर (MeshList.h में वापस) Mesh का संदर्भ है - लेकिन अभी तक इसे घोषित नहीं किया गया है। इसलिए, उदाहरण के लिए, आपकी C2143 त्रुटि।

+0

@ildjarn, यह दिलचस्प है क्योंकि मैंने कभी भी कहीं भी नहीं खोजा है। क्या मैं पूछ सकता हूं क्यों? – chris

+0

@ क्रिस: आपको उन लोगों से पूछना होगा जिन्होंने सी ++ डिजाइन किया है! – ildjarn

+0

@ildjarn: क्या आप निश्चित हैं?मैं वास्तव में काफी यकीन है कि विपरीत सच है। मुझे यह भी याद रखना है कि मानक ने कहा है कि एक वर्ग को मित्रवत करने के लिए अपने सभी कार्यों को मित्रवत करने के बराबर था ... मुझे लगता है कि मुझे लगता है कि उद्धरण के लिए मुझे देखना होगा। –

6

क्योंकि आप फ़ाइल Mesh.h में #include "MeshList.h" है, तो फ़ाइल MeshList.h पहले संकलित किया जाएगा, और कक्षा Mesh अभी तक घोषित नहीं किया गया है यह। इसके लिए संकलक सोचेंगे कि त्रुटि रेखा में Mesh एक परिवर्तनीय नाम है जिसे इससे पहले कोई प्रकार नहीं मिला है, इसलिए त्रुटि।

#include <iostream> 


class foo; 

class bar 
{ 
public: 
    void barfunc(foo &f); 
}; 

class foo 
{ 
private: 
    friend void bar::barfunc(foo &f); 
    int i; 
public: 
    foo() 
    { 
     i = 0; 
    } 
    void printi() 
    { 
     std::cout << i << '\n'; 
    } 
}; 

void bar::barfunc(foo &f) 
{ 
    f.i = 5; 
} 


int main() 
{ 
    foo f; 
    bar b; 
    b.barfunc(f); 
    f.printi(); 
    return 0; 
} 
4

समस्या: चक्रीय अपने शामिल में निर्भरता

यह एक friend सदस्य समारोह बनाने का एक उदाहरण है। दुर्भाग्यवश, त्रुटि संदेश आदर्श से कम है।


समाधान: आप पूरी कक्षा से दोस्ती करते हैं, तो एक भी समारोह के बजाय, तो आप वर्ग के एक आगे घोषणा चक्र को तोड़ने के लिए उपयोग कर सकते हैं।

// Mesh.h 
#ifndef _MESH_H 
#define _MESH_H 

#include <iostream> 

class MeshList; 

class Mesh 
{ 
private: 
    unsigned int vboHandle_; 
    friend class MeshList; 
public: 
    inline void Out() {std::cout << vboHandle_;} 
}; 
#endif 

कुछ (व्यक्तिपरक) के दिशा निर्देशों:

  • इसे बदलने के लिए अगर यह टूट जाता है अपनी क्षमता के विपरीत क्रम में सामान को शामिल करें, वह है: एसटीएल पहले, 3 पार्टी हेडर दूसरा, अपने अपने मिडलवेयर स्टैक तीसरे, वर्तमान परियोजना में चौथाई शामिल है और वर्तमान पुस्तकालय में पांचवां शामिल है। इस तरह, यदि कोई संघर्ष है, तो उम्मीद है कि त्रुटि आपके हेडर को इंगित करेगी।

  • कक्षा में private सामान से पहले सामान रखो। कक्षा के ग्राहक केवल सार्वजनिक इंटरफ़ेस से चिंतित हैं, उन्हें इससे पहले कि वे इसे प्राप्त करने से पहले सभी गंदे कार्यान्वयन विवरणों से गुजरने की आवश्यकता हो।

+0

जैसा कि मैं समझता हूं, अगर आपके मित्र की घोषणा पहले उपयोग से ऊपर है तो आपको आगे की घोषणा की आवश्यकता नहीं है। (मैंने वीएस में इसी तरह के उदाहरण w/o 'class मेशलिस्ट' का परीक्षण किया है और यह काम करता है।) – anxieux

+0

@anxieux: मैं वास्तव में पूरी तरह से समझ नहीं पाया कि 'दोस्त वर्ग' के नाम पर नाम किस प्रकार प्राप्त नहीं किया गया था; इसलिए मैंने इस प्रकार की घोषणा करने की आदत ली है। थोड़ा अधिक verbose, शायद, लेकिन हे: यह 100% समय काम करता है! –

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