在范围内定义的名称隐藏在任何外部范围内的同名声明。像这样:
int name; // global name
void f() {
int name; // name 1, hides global name
for (int i = 0; i < 10; i++) }
int name; // name 2, hides name 1 and global name
name = 3; // assigns 3 to name 2
}
name = 4; // assigns 4 to name 1
}
int other = name; // copies value of global name into other
当两个或多个具有相同名称的函数被声明在同一范围内时,名称被重载:
// two functions in global scope:
void f();
void f(int);
void g() {
f(); // ok: calls first version of f
f(1); // ok: calls second version of f
}
不同作用域中的定义不定义重载集,因为内部作用域中的声明隐藏了任何外部作用域中的同名。
class cl1 {
public:
// hides global f's:
void f();
void g() {
f(); // ok: calls cl1::f()
f(1); // error: no f takes an int; global f(int) is hidden
}
};
当然,在同一作用域中定义多个函数仍然定义了重载,即使在外部作用域中存在具有相同(隐藏)名称的函数。
class cl2 {
public:
// these hide global f's, and provided overloads:
void f();
void f(int);
void g() {
f(); // calls cl2::f()
f(1); // calls cl2::f(int)
}
};
类定义提供了一个新的范围,因此关于名称隐藏和重载的规则适用于类中定义的名称。
class cl3 : public cl2 {
void g() {
f(); // calls cl2::f()
f(1); // calls cl2::f(int)
}
};
class cl4 : public cl2 {
// hides all f's:
void f();
void g() {
f(); // ok: calls cl4::f();
f(3); // error: no f takes an int; global f(int) and cl2::f(int) are hidden
}
};
class cl5 : public cl2 {
// hides all f's and provides overloads:
void f();
void f(int);
void g() {
f(); // ok: calls cl5::f()
f(3); // ok: calls cl5::f(int)
}
};
您还可以使用与基类中的任何签名都不匹配的签名。毕竟那些基类函数的名字是隐藏的。
class cl5 : public cl2 {
public:
// hides all f's:
void f(std::string);
void g() {
f(); // error: no f taking no arguments
f(3); // error: no f taking int
std::string arg("test");
f(arg); // ok: calls cl5::f(std::string)
}
};
最后,如果你想编写一个派生类,为基类中定义的重载函数集添加签名,你必须将这些重载函数的名称添加到派生类中:
class cl6 : public cl2 {
public:
using cl2::f; // pull cl2::f into current scope
void f(std::string); // add overload to names from cl2
void g() {
f(); // ok: calls cl2::f()
f(3); // ok: calls cl2::f(int)
std::string arg("test");
f(arg); // ok: calls cl6::f(std::string)
}
};