Name Lookup and Class Scope

Name Lookup for Class Member Declarations

Name lookup is the process of finding which declarations match the use of a name. In C++, there are two rules used in name lookup.

The first rule is 3-step name lookup, which explains as follows:

  • First, look for a declaration of the name in the block in which the name was used. Only names declared before the use are considered.
  • If the name isn’t found, look in the enclosing scpoe(s).
  • If no declaration is found, then the program is in error.

The second rule is 2-step name lookup, which explains as follows:

  • First, the member declarations are compiled.
  • Function bodies are compiled only after the entire class has been seen.

The 2-step name lookup applies only to the body of a member function of a class. Names used in declaration, including names used for the return type and types in the parameter list, muste be seen before they are used, that menas, 3-step name lookup must be applied in this case. For example:

typedef double Money;
string bal;

class Account {
public:
    Money balance() { return bal; }
private:
    Money bal;
    // ...
};

When the compiler sees the declaration of the balance function, it will look for a declaration of Money in the Account class. The compiler considers only declarations inside Account that appears before the use of Money. Because no matching member is found, the compiler then looks for a delcaration in the enclosing scope(s). In this example, the compiler will find the typedef of Money. That type will be used for the return type of the function balance and as the type for the only after the entire class is seen. Thus, the return inside that function returns the member named bal, not the string from the outer scope.

Type Names Are Special

Ordinarily, an inner scope can redefine a name from an outer scope even if that name has already been used in the inner scope. However, in a class, if a member used a name from an outer scope and that name is a type, then the class may not subsequently redefine that name:

typedef double Money;
string bal;

class Account {
public:
    Money balance() { return bal; }
private:
    typedef double Money; // error: cannot redefine Money
    Money bal;
    // ...
};

It is worth noting that even though the definition of Money inside Account uses the name type as the definition in the outer scope, this code is still in error.

Although it is an error to redefine a type name, compilers are not required to diagnose this error. Some compilers will quietly accept such code, even though the program is in error.

Tips

Definitions of type names usually should appear at the beginning of a class. That way any member that uses that type will be seen after the type name has already been defined.

发表评论

电子邮件地址不会被公开。 必填项已用*标注

2 × 5 =

13 − 7 =