考虑以下代码:
#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(); }
g ++的输出是:
D::S
D::S
我的问题是:
D::S
S s;
为什么f()
引用D::S
而非::S
?答案 0 :(得分:5)
在班级searchList = ['Long','Short']
strTests = [
"ABC Long Short DEF",
"XYZ Short Long ZYX",
"XYZ Short lbah ZYX",
"XYZ blal Long ZYX",
"I am a random String",
"I am a really Long string with no Short Parts"
]
# test against test cases for ["Long","Short"]
results = [getFirst(string, searchList) for string in strTests]
print results
['Long', 'Short', 'Short', 'Long', None, 'Long']
# test against test cases for more generic case
searchList = ['Long', 'Short', 'really']
results = [getFirst(string, searchList) for string in strTests]
print results
['Long', 'Short', 'Short', 'Long', None, 'really']
的正文中,名称D::S
显然是指自己。这被称为&#34;注入的类名&#34;。您可以将其视为S
中有一个公共成员typedef,其名称为D::S
。
- (1)如何工作 - 我会认为基类的名称是D :: S具体而言
S
派生自X
,因为您在D::S
的基类列表中这样说。
派生类可以访问基类中声明的名称,因此X
中的名称查找首先查看自己的成员及其基类&#39;成员,然后在X
之外的封闭范围中查找名称。由于注入的班级名称X
是S
的成员,因此可以在D::S
找到,这就是为什么(1)有效。找不到类型X
,因为名称查找找到了注入的类名,并且从不查看封闭范围(如果 找到::S
代码将无法编译,因为::S
不是::S
)的基类。
作为类比,请使用X
中声明的成员typedef来考虑此示例:
D::S
这是因为名称namespace D {
struct S {
struct S { S(){std::cout << "D::S\n";} };
typedef S AnotherName;
};
}
struct X : D::S {
X() : AnotherName() { }
};
在基类中找到,并且是基类类型AnotherName
的同义词。注入的类名称的工作方式类似,只是注入的名称是类&#39;自己的名字D::S
,而不是S
等其他名称。
- 是否需要工作(1)和(2)?
是
(2)有效,因为AnotherName
是D::S
的完全限定名称,因此它引用相同类型,但使用其&#34;全名&#34;非成员必须用来引用该类型。
- 为什么S s;在f()里面是指D :: S而不是:: S?
因为像构造函数一样,S
是f()
的成员,所以名称查找首先查看X
(及其基类)的范围,因此找到注入的类名。它永远不会在全局范围内看到类型X
,因为它将名称::S
视为基类的成员并停止查找。