【问题标题】:Is a namespace required when referring to the base class引用基类时是否需要命名空间
【发布时间】:2010-11-25 13:20:02
【问题描述】:

我有这样的代码:

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

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

【问题讨论】:

  • 如果这不是秘密,哪个编译器会抱怨?

标签: c++ inheritance namespaces language-lawyer name-lookup


【解决方案1】:

在类定义B里面是OK的。这就是所谓的注入类名

这也指模板(不包括依赖碱基)。例如

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 : 在看到类名之后,类名被插入到声明它的范围内。类名也是 插入到类本身的范围内;这被称为 注入类名。出于访问检查的目的, injection-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  
};

14.6.1 谈到模板中注入的类名。在这里粘贴太长了。 小时

【讨论】:

  • 那么为什么编译器会抱怨呢?
  • @Raveline:因为我忘记了 {} :) 已编辑
  • 据我所知,9.2/2 只说类名“Derived”被注入到 Derived 本身。它没有说任何关于基类的内容
  • @Steve:由于这个名字就像类中的一个公有名,所以被派生类继承了。
  • @Armen:啊哈!是的,就是这样。所以因为 B 被注入到 B 中,所以它也在 Derived 中。
猜你喜欢
  • 1970-01-01
  • 2011-07-24
  • 1970-01-01
  • 1970-01-01
  • 2014-03-09
  • 2014-07-20
  • 1970-01-01
  • 2013-02-17
  • 2012-08-01
相关资源
最近更新 更多