名称查找合格的基类

时间:2015-06-16 23:06:19

标签: 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(); }

g ++的输出是:

D::S
D::S

我的问题是:

  • (1)如何工作 - 虽然我认为基类的名称是D::S
  • 是否需要工作(1)和(2)?
  • S s;为什么f()引用D::S而非::S

1 个答案:

答案 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之外的封闭范围中查找名称。由于注入的班级名称XS的成员,因此可以在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)有效,因为AnotherNameD::S的完全限定名称,因此它引用相同类型,但使用其&#34;全名&#34;非成员必须用来引用该类型。

  
      
  • 为什么S s;在f()里面是指D :: S而不是:: S?
  •   

因为像构造函数一样,Sf()的成员,所以名称查找首先查看X(及其基类)的范围,因此找到注入的类名。它永远不会在全局范围内看到类型X,因为它将名称::S视为基类的成员并停止查找。