2014-12-23 122 views
0

我正在爲學校做家庭作業。對於主循環,我循環遍歷對象並調用它們的Update函數,每個對象都有兩個對象指針用於創建鏈表。我將這些指針設爲私有,並使GetNext女巫提供了兩個朋友函數Next指針,SetPointers女巫設置指針。這些函數在ObjectManager類中,它們是私有的。我似乎無法讓對象類訪問其定義而不會導致其他錯誤。朋友功能減速無法訪問功能聲明

對象類:

namespace Tmpl8{ 
    class Colider; 

    class ObjectManager; 
    class PhysicsManager; 

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

     virtual void Update(); 

    private: 
     Object* Next; 
     Object* Previus; 

     friend Object* ObjectManager::GetNext(Object* object); 
     friend void ObjectManager::SetPointers(Object* object, Object* next, Object* previus); 
    }; 

中的ObjectManager類:

namespace Tmpl8{ 
    class Object; 
    class GameObject; 
    class Colider; 

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

     void Update(); 
     void Remove(Object* object); 
     void Add(Object* object); 

    private: 
     void Resolve(); 
     std::vector<Object*> removeList; 
     std::vector<Object*> addList; 

     Object* first; 
     Object* last; 

     Object* GetNext(Object* object); 
     void SetPointers(Object* object, Object* next, Object* previus); 
    }; 

的的GetNext功能

Object* ObjectManager::GetNext(Object* object) 
    { 
     return object->Next; // this gives the error Tmpl8::Object::Next(delecared at...) is inaccessible 
    } 

生成日誌:

1>c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\object.h(25): error C2248: 'Tmpl8::ObjectManager::GetNext' : cannot access private member declared in class 'Tmpl8::ObjectManager' 
    1>   c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\manager.h(29) : see declaration of 'Tmpl8::ObjectManager::GetNext' 
    1>   c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\manager.h(12) : see declaration of 'Tmpl8::ObjectManager' 
    1>c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\object.h(26): error C2248: 'Tmpl8::ObjectManager::SetPointers' : cannot access private member declared in class 'Tmpl8::ObjectManager' 
    1>   c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\manager.h(30) : see declaration of 'Tmpl8::ObjectManager::SetPointers' 
    1>   c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\manager.h(12) : see declaration of 'Tmpl8::ObjectManager' 
    1> manager.cpp 
    1>c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\object.h(25): error C2027: use of undefined type 'Tmpl8::ObjectManager' 
    1>   c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\object.h(11) : see declaration of 'Tmpl8::ObjectManager' 
    1>c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\object.h(26): error C2027: use of undefined type 'Tmpl8::ObjectManager' 
    1>   c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\object.h(11) : see declaration of 'Tmpl8::ObjectManager' 
    1>manager.cpp(40): warning C4018: '<' : signed/unsigned mismatch 
    1>manager.cpp(45): warning C4018: '<' : signed/unsigned mismatch 
    1>manager.cpp(57): error C2248: 'Tmpl8::Object::Next' : cannot access private member declared in class 'Tmpl8::Object' 
    1>   c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\object.h(22) : see declaration of 'Tmpl8::Object::Next' 
    1>   c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\object.h(14) : see declaration of 'Tmpl8::Object' 
    1> object.cpp 
    1>c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\object.h(25): error C2248: 'Tmpl8::ObjectManager::GetNext' : cannot access private member declared in class 'Tmpl8::ObjectManager' 
    1>   c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\manager.h(29) : see declaration of 'Tmpl8::ObjectManager::GetNext' 
    1>   c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\manager.h(12) : see declaration of 'Tmpl8::ObjectManager' 
    1>c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\object.h(26): error C2248: 'Tmpl8::ObjectManager::SetPointers' : cannot access private member declared in class 'Tmpl8::ObjectManager' 
    1>   c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\manager.h(30) : see declaration of 'Tmpl8::ObjectManager::SetPointers' 
    1>   c:\all svn\student.141960.school_projects\programing\block 2\micro machines_02\manager.h(12) : see declaration of 'Tmpl8::ObjectManager' 
    1> Generating Code... 

==========構建:0成功,1失敗,0最新,0跳過==========

+1

這個'friend'聲明甚至不是有效的(因爲ObjectManager還不知道);大概你只是把最後一個錯誤貼到我們身上而忽略了其餘的一切? –

+0

我不明白爲什麼它不是有效的? – theRealFlobo

+1

在編譯器知道'ObjectManager'具有這樣一個成員函數之前,你正試圖使'ObjectManager'的成員函數成爲朋友。這是違法的。你的一個編譯器錯誤的是告訴你,(除非MSVS在這方面有一些可怕的擴展,我不知道的) –

回答

0

有兩種解決方案,我知道(假設你不能把ObjectManager的整個聲明放在Object之前)。簡單的一種是:

friend class ObjectManager; 

你已經邀請好友兩種方法,爲什麼不朋友所有的人?更復雜的一個涉及使用passkey的,在這種情況下,顯然是雪上加霜:

template <typename T> 
class PassKey; 

class ObjectManager; 

class Object { 
public: 
    Object* GetNext(PassKey<ObjectManager>) { return Next; } 
    void SetPointers(PassKey<ObjectManager>, Object*, Object*) { .. } 
}; 

有:

template <typename T> 
class PassKey { 
    friend T; 
    PassKey() { } 
}; 

這裏,GetNext()SetPointers()Object公共職能,但它們需要一個PassKey這是私人建造,其唯一的朋友是ObjectManager。因此,ObjectManager可以這樣做:

Object* ObjectManager::GetNext(Object* object) 
{ 
    return object->GetNext(PassKey<ObjectManager>()); 
} 

然而,這真的muddles的界面相比,只邀請好友全班同學在我看來,是什麼沒有好處。

+0

我剛做了ObjectManager的一個朋友,感謝Brian和@LightnessRacesinOrbit – theRealFlobo