friend darf nicht auf protected member zugreifen? ?-)



  • Hi!

    folgender Code:

    CommandEmitterBase.h

    class CommandQueue;
    
    class CommandEmitterBase
    {
    	public:
    		CommandEmitterBase(CommandQueue& q);
    		virtual ~CommandEmitterBase() {}
    
    		virtual void poll() = 0;
    
    	protected:
    		void emitCommand(Command* command); // CommandEmitterBase.h:30
    
    	private:
    		CommandQueue& queue;
    };
    

    CommandQueue.h

    class CommandQueue
    {
    	public:
    		CommandQueue();
    		~CommandQueue() {}
    
    		Command* getNextCommand();
    		void pollEmitters();
    		void addEmitter(CommandEmitterBase* emitter);
    
    	private:
    		std::queue<Command*> queue;
    		std::vector<CommandEmitterBase*> emitters;
    
    		friend void CommandEmitterBase::emitCommand(Command* command); // CommandQueue.h:34
    		typedef std::vector<CommandEmitterBase*>::iterator EmitterIter;
    };
    

    Der GCC 3.4.1 meint dazu:

    src/input/CommandEmitterBase.h:30: error: `void CommandEmitterBase::emitCommand(Command*)' is protected
    src/input/CommandQueue.h:34: error: within this context
    

    Was ist an dem Code falsch? Ich versteh den Fehler nicht? πŸ˜•

    BTW: Eine etwas aeltere Version des Programms (die betreffenden Codeteile wurden aber IIRC nicht geandert) kompilierte mit dem GCC 3.3.1 anstandslos πŸ˜•



  • Wie Du es geschrieben hast, kann CommandEmitterBase::emitCommand auf alle protected und private Elemente von CommandQueue zugreifen.

    Die friend-Deklaration muss in der Klasse stehen, auf die Zugriff erteilt werden soll.



  • MFK schrieb:

    Wie Du es geschrieben hast, kann CommandEmitterBase::emitCommand auf alle protected und private Elemente von CommandQueue zugreifen.

    Das ist auch Sinn der Sache πŸ˜‰

    genauer gesagt soll CommandEmitterBase::emitCommand es allen Kindern von CommandEmitterBase erlauben, neue Elemente in CommandQueue::queue hinzuzufuegen:

    /*
     * derivates of CommandEmitterBase can use this function to emit Commands to
     * the CommandQueue;
     */
    void CommandEmitterBase::emitCommand(Command* command)
    {
    	queue.queue.push(command);
    }
    

    Nur will das Ganze aus mir unersichtlichen Gruenden nicht kompilieren πŸ˜•



  • So steht es im Standard: Β§11.4.7:

    "A name nominated by a friend declaration shall be accessible in the scope of the class containing the friend declaration. The meaning of the friend declaration is the same whether the friend declaration appears in the private, protected or public (9.2) portion of the class member-specification."

    Da von deiner CommandQueue Klasse heraus CommandEmitterBase::emitCommand nicht accessible ist, ist die friend Deklaration illegal.



  • hm da hat er recht, die ist ja protected die methode
    du musst IMHO die ganze CommandQueue-Klasse als friend klasse der CommandEmitterBase-Klasse machen.
    also

    class CommandEmitterBase
    {
      friend CommandQueue;
      // ...
    }
    

    korrigiert mich wenn ich mich irre πŸ˜‰


Log in to reply