为什么编译成功?



这段代码编译的原因是什么?

#include <iostream>
using namespace std;
class being {
public:
void running(char c) {
cout << "No one know ";
}
};
class human :public being {
public:
using being::running;
void running(char y) {
cout << "I am a human";
}
};
int main() {
human o;
o.running('A');
return 0;
}

the output : "I am a human" 

我的意思是(我期望有错误(重新定义函数在人类类))像这样:以下代码编译:

#include <iostream>
using namespace std;
class being {
public:
int v;
};
struct human :public being {
public:

double v;
};
int main() {
human o;
o.v = 55.2;
return 0;
}

但是当我加上(使用being::v)

#include <iostream>
using namespace std;
class being {
public:
int v;
};
struct human :public being {
public:
using being::v;
double v;
};
int main() {
human o;
o.v = 55.2;
return 0;
}
错误C2086: 'int being::v': redefinition

为什么第一个代码中没有出现这个错误?

这是使用声明的预期行为。

如果派生类已经有一个具有相同名称、参数列表和限定条件的成员,则派生类成员隐藏或覆盖(不与)从基类引入的成员冲突。

所以human::running(char)隐藏了being::running(char)而不是冲突。

编辑

第二个代码片段格式错误。对于来自标准的数据成员,[namspace .udecl]/10:

如果使用声明命名的声明位于另一个声明的目标范围内,可能与它冲突([basic.scope.scope]),并且任何一方都可以从另一方访问,则程序是病态的。如果在同一作用域内使用using声明命名的两个声明可能会发生冲突,其中一个可以从另一个访问,并且它们不都声明函数或函数模板,则程序是病态的。

[例6:

...
namespace B {
int i;
...
}
void func() {
int i;
using B::i;                           // error: conflicts
...
...

所以你不能usingbeing::vhuman::v冲突。但是对于成员函数,[namspace .udecl]/11:

由类C中的using声明器命名的声明集不包括与C中的函数或函数模板的声明相对应(因此会与之冲突)的基类的成员函数和成员函数模板。

[示例7:

struct B {
virtual void f(int);
virtual void f(char);
void g(int);
void h(int);
};
struct D : B {
using B::f;
void f(int);      // OK: D​::​f(int) overrides B​::​f(int);
using B::g;
void g(char);     // OK
using B::h;
void h(int);      // OK: D​::​h(int) hides B​::​h(int)
};
...

最新更新