M.M*_*M.M 0 c++ inheritance name-lookup
考虑以下代码:
#include <iostream>
namespace D
{
struct S { S(){std::cout << "D::S\n";} };
}
struct S { S(){std::cout << "S\n";} };
struct X: D::S
{
X(): S() {} // (1)
// X(): D::S() {} // (2)
void f() { S s; }
};
int main() { X x; x.f(); }
Run Code Online (Sandbox Code Playgroud)
g ++的输出是:
D::S
D::S
Run Code Online (Sandbox Code Playgroud)
我的问题是:
D::S具体的,但我会有S s;内部f()参考D::S而不是::S?在类的主体内,D::S名称S显然是指自己.这称为"注入类名".您可以将其视为D::S具有自己名称的公共成员typedef S.
- (1)如何工作 - 我会认为基类的名称是D :: S
X派生自D::S,因为你在基类列表中这么说X.
派生类可以访问基类中声明的名称,因此名称查找X首先查看其自己的成员及其基类的成员,然后在外部的封闭范围中查找名称X.因为注入的类名S是其成员D::S,所以它被发现X,这就是为什么(1)有效.::S找不到类型,因为名称查找找到了注入的类名,并且从不在封闭范围内查找(如果它确实发现::S代码不能编译,因为::S它不是基类X).
作为类比,请考虑使用在D::S以下位置声明的成员typedef的此示例:
namespace D {
struct S {
struct S { S(){std::cout << "D::S\n";} };
typedef S AnotherName;
};
}
struct X : D::S {
X() : AnotherName() { }
};
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为名称AnotherName可以在基类中找到,并且是基类类型的同义词D::S.注入的类名称的工作方式类似,只是注入的名称是类的自己的名称S,而不是其他名称AnotherName.
- (1)和(2)都需要工作吗?
是.
(2)作品因为D::S是完全限定的名称S所以它指的是同一类型,但使用其非全员必须使用的"全名"来引用该类型.
- 为什么S s; 在f()里面是指D :: S而不是:: S?
因为像构造函数一样,f()是X名称查找的成员X首先在(及其基类)的范围内查找,因此查找注入的类名.它永远不会::S在全局范围内看到类型,因为它将名称S视为基类的成员并停止查找.
| 归档时间: |
|
| 查看次数: |
140 次 |
| 最近记录: |