我有这样的代码:
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 ++标准说的是什么?
答案 0 :(得分:11)
在类定义B里面就可以了。这就是所谓的 注入的类名 。
这也指模板(不计入依赖碱基)。 E.g。
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:在看到类名后立即将类名插入到作用域中。类名也是 插入到类本身的范围内;这被称为 注入的类名。出于访问检查的目的, inject-class-name被视为公共成员名称。
从这个定义可以看出,类本身的名称可以从类中公开访问,因此可以在派生类中使用。这证明了我关于B和N :: B的关系是正确的,因为名字B是继承的
顺便说一句,这也解释了为什么以下内容无效:
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谈论模板中注入的类名。粘贴这里太长了。 HTH