友元函数减速无法访问函数声明

时间:2014-12-23 11:32:12

标签: c++ pointers visual-c++ polymorphism friend

我正在为学校做家庭作业。对于主循环,我循环通过Objects并调用它们的Update函数,每个Object都有两个Object指针用于制作链表。我将这些指针设为私有,并使两个朋友函数GetNext提供了Next指针,而SetPointers则设置了指针。这些函数在ObjectManager类中,它们是私有的。我似乎无法让Object类访问其定义而不会导致其他错误。

对象类:

   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 个答案:

答案 0 :(得分: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>());
}

然而,这真的混淆了界面,在我认为与仅仅是为了全班同学交友时没有任何好处。