代码之家  ›  专栏  ›  技术社区  ›  user9876

在引用基类时是否需要命名空间

  •  12
  • user9876  · 技术社区  · 15 年前

    我有这样的代码:

    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?
     };
    

    是否需要派生引用其基类的命名空间限定符?GCC和MSVC对编写的代码很满意,但是另一个编译器会抱怨,除非我把名称空间放进去。C++标准是怎么说的?

    1 回复  |  直到 6 年前
        1
  •  11
  •   TreyA    6 年前

    在类定义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
    };
    

    一般来说,基类(以及类本身)可以在类定义中引用,而无需限定或模板参数。

    引用标准:

    9.2:类名插入到一个作用域中,在该作用域中看到类名后立即声明它。类名也是 插入到类本身的作用域中;这称为 注入类名。出于访问检查的目的 注入的类名被视为公共成员名。

    根据这个定义,类本身的名称可以从类中公开访问,因此在派生类中可用。这证明了我关于B和N::B是可以的观点,因为名称B是继承的

    顺便说一句,这也解释了以下内容无效的原因:

    template <class T> class B{};
    template <class T> class C: public B<T>
    {
         void 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谈到模板中注入的类名。在这儿贴太长了。 高温高压

    推荐文章