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

use*_*876 12 c++ inheritance namespaces language-lawyer name-lookup

我有这样的代码:

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?
 };
Run Code Online (Sandbox Code Playgroud)

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

Arm*_*yan 11

在类定义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
};
Run Code Online (Sandbox Code Playgroud)

通常,基类(和类本身)可以在类定义中引用,而不需要限定条件或模板参数.

标准引用:

9.2:在看到类名后立即将类名插入到作用域中.类名也插入到类本身的范围内; 这被称为注入类名.出于访问检查的目的,inject-class-name被视为公共成员名称.

从这个定义可以看出,类本身的名称可以从类中公开访问,因此可以在派生类中使用.这证明了我对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  
};
Run Code Online (Sandbox Code Playgroud)

14.6.1谈谈模板中注入的类名.粘贴这里太长了.心连心

  • @Armen:啊哈!是的,就是这样.因此,因为B被注入B,因此它也在Derived中. (3认同)