2010-11-25 9 views
12

I-Code wie diese:erforderlich, um ein Namespace, wenn auf die Basisklasse Bezug

namespace N { 
    class B { 
    public: 
     virtual void doStuff(B *) = 0; 
    }; 
} 

// not in a namespace 
class Derived : public N::B { 
    public: 
     void doStuff(B *); // Should this be N::B, or is B ok? 
}; 

Benötige ich den Namespace-Qualifier wo Abgeleitet bezieht sich auf das Basisklasse? GCC und MSVC sind zufrieden mit dem Code wie geschrieben, aber ein anderer Compiler beschwert sich, wenn ich den Namespace nicht einfüge. Was sagt der C++ Standard?

+1

Welcher Compiler beschwert sich, wenn das kein Geheimnis ist? –

Antwort

11

Innerhalb der Klassendefinition B ist OK. Das ist der so genannte Name der eingespritzten Klasse.

Dies bezieht sich auch auf Vorlagen (ohne abhängige Basen). Z.B.

template <class T> class B{}; 
template <class T> class C: public B<int> 
{ 
    void f(B* p) {} //same as B<int>* p 
    void f(C* p) {} //same as C<T>* p 
}; 

Im Allgemeinen kann die Basisklasse (und die Klasse selbst) innerhalb der Klassendefinition ohne Qualifizierungs- oder Vorlagenargumente angegeben werden.

Zitate von der Norm:

9,2: A class-name in den Bereich, in dem es eingesetzt ist, sofort erklärt wird, nachdem der Klassenname zu sehen ist. Der Klassenname ist auch in den Bereich der Klasse selbst eingefügt; Dies ist bekannt als injected-class-name. Für die Zwecke der Zugriffsprüfung wird der Name der injected-class behandelt, als ob es ein öffentlicher Membername wäre.

Aus dieser Definition folgt, dass der Name der Klasse selbst von der Klasse aus öffentlich zugänglich ist und daher in abgeleiteten Klassen verfügbar ist. Welche meinen Punkt über B B Btw

vererbt wird

ist OK zusammen mit N :: B, weil der Name beweist, dies erklärt auch, warum die folgende ist ungültig: Namen

template <class T> class B{}; 
template <class T> class C: public B<T> 
{ 
    voiid f(B* p){} //ERROR 
    // the above is invalid!! Base class is dependent therefore 
    //its scope is not considered during unqualified name lookup 
    void g(typename C::B* p){} //this is valid, same as B<T>* p 
}; 

14.6.1 spricht über injiziert Klasse in Vorlagen. Es ist viel zu lang, um hier einzufügen. Hth

+0

Warum beschwert sich der Compiler? – Raveline

+0

@Raveline: Weil ich die {} vergessen habe :) Edited –

+0

Soweit ich sehen kann, 9.2/2 sagt nur, dass der Klassenname "Derived" in Derived selbst injiziert wird. Es sagt nichts über Basisklassen aus –

Verwandte Themen