Seite 1 von 1

Problem mit protected

Verfasst: 27. Juli 2010 15:11
von christophr
Hi,

ich stehe gerade ziemlich auf dem Schlauch. Vermutlich sehe ich einfach den Wald vor lauter Bäumen nicht mehr. Hier mein Problem:

Compilermeldung:

Code: Alles auswählen

[...]/AbstractRelationNode.hpp:87: error: 'virtual void AbstractRelationNode::setInputChannels(unsigned int, PathID)' is protected
[...]/AbstractFilterRelationNode_impl.hpp:72: error: within this context
Und hier die Quelldateien:

Code: Alles auswählen

// AbstractRelationNode.hpp
class AbstractRelationNode : public Observable<IAbstractRelationNode>
{
    [...]
    protected:
    virtual void setInputChannels( const unsigned int aChannels, const PathID aPath ) = 0;  // <-- Hier meckert der Compiler (Zeile 87)
    [...]
};

Code: Alles auswählen

// AbstractFilterRelationNode_impl.hpp
template< typename T >
void
AbstractFilterRelationNode<T>::outputChannelsChanged( AbstractFilter<T>* aFilter, unsigned int aOutputChannels )
{
	// Signal the change of the output channels to the connected relation node:
	if (0 != this->next(0))
	{
		this->next(0)->setInputChannels( aOutputChannels, this->next(0)->incomingPath(this) );  // <-- Hier meckert der Compiler (Zeile 72)
	}
}

Code: Alles auswählen

// AbstractFilterRelationNode.hpp
template< typename T >
class AbstractFilterRelationNode : public AbstractRelationNode, protected Observer< IAbstractFilter<T> >
{
    [...]
    protected:
    // From AbstractRelationNode:
    virtual void setInputChannels( const unsigned int aChannels, const PathID aPath );

    // From Observer< IAbstractFilter<T> >
    virtual void outputChannelsChanged(AbstractFilter<T>* aFilter, unsigned int aOutputChannels);

    [...]
};


Normalerweise darf ich auf protected-Elemente im Zuge der Vererbung doch zugreifen. Wahrscheinlich habe ich so etwas simples übersehen, dass ich es einfach immer noch übersehe.

Danke an alle, die mal drüberschauen.

Gruß,
Christoph

P.S.: Gab es nicht mal Tags, die den Code farbig einfärben? Oder war das in einem anderen Forum?

Verfasst: 27. Juli 2010 18:27
von franzf
Farbige code-tags gibts hier leider nicht :(

Code: Alles auswählen

#include <iostream>
using namespace std;

class Base {
    protected:
        virtual void foo() =0;
};

class Derived : public Base {
    void foo() {
        cout << "Derived::foo()" << endl;
    }
    public:
        void bar() {
            // Derived* b = new Derived; // geht problemlos
            Base* b = new Derived; // dein nex() wird nur einen Basisklassenzeiger zurückgeben, oder?
            b->foo(); // dann krachts hier :P
        }
};

int main() {
    Derived d;
    d.bar();
}

Code: Alles auswählen

call_base_virt_protected.cpp: In member function »void Derived::bar()«:
call_base_virt_protected.cpp:7: Fehler: »virtual void Base::foo()« ist geschützt
call_base_virt_protected.cpp:17: Fehler: in diesem Zusammenhang
Sollte das Problem klar machen ;)

Verfasst: 27. Juli 2010 19:09
von christophr
Nun muss ich leider bekennen, dass ich ob der doch mittlerweile recht anschaulichen C++-Jahre in einigen Punkten noch nicht aus der 1. Klasse raus bin. :oops:

Ich habe das Beispiel mal erweitert:

Code: Alles auswählen

#include <iostream> 
using namespace std; 

class Base { 
    protected: 
		virtual void foo() = 0;
		static int var;
}; 

int Base::var = 0;

class Derived : public Base { 
    void foo() { 
        cout << "Derived::foo()" << endl; 
    } 
    public: 
        void bar() { 
            //Derived* b = new Derived; // geht problemlos 
            Base* b = new Derived; // dein nex() wird nur einen Basisklassenzeiger zurückgeben, oder? 
            //b->foo(); // dann krachts hier :P 
			var++;
			cout << var << endl;
        } 
}; 

int main() { 
    Derived d; 
    d.bar();
	d.bar();
}
Also meine Frage aus der ersten Klasse:
Wieso darf ich auf var zugreifen, auf foo() aber nicht? Sie sind doch beide im selben Sichtbarkeitsbereich.

(Ich kann selber kaum glauben, dass ich bisher noch nie auf dieses Problem gestoßen bin...)

Gruß,
Christoph

Verfasst: 27. Juli 2010 20:07
von franzf
christophr hat geschrieben:Wieso darf ich auf var zugreifen, auf foo() aber nicht? Sie sind doch beide im selben Sichtbarkeitsbereich.
Sie sind im selben Sichtbarkeitsbereich, ja (müsste auch nichtmal static sein). Das Problem ist der Zugriff. Wenn du die Variable/Funktion/... über "this" ansprichst, ist der Zugriff auf den protected Member OK. Sobald du das über ein Objekt machst, muss das Objekt vom selben Typen sein wie die aufrufende Klasse - und Derived ist kein Base.

Bin aber leider nicht standardbewandert genug, um die korrekten Termini zu verwenden, und eine Paragraphengeführte Argumentation zu führen :P

Verfasst: 27. Juli 2010 20:27
von christophr
"Und plötzlich fiel es ihm wie Schuppen von den Augen..."

Besten Dank für die kurze Nachhilfe.

Gruß,
Christoph


P.S.: static war die schnellste Möglichkeit, einen initialisierten Zähler zu erhalten. (Nur für Beispiele zu empfehlen)