我有两个简单的类,希望通过传递stuff
值来访问公共方法int
。为什么我不能用Bar的实例做到这一点?它不应该继承公共方法的东西。类型提示给出了int a
参数,但它没有编译。
class Foo
{
public:
int a;
void stuff(int a){ std::cout << a << std::endl; }
};
class Bar : public Foo
{
protected:
void stuff() { std::cout << "hello world"; }
};
void main()
{
Bar b
b.stuff(3);
}
答案 0 :(得分:6)
因为Bar::stuff
隐藏了Foo::stuff
(只有在执行重载解析时名称才重要,所以忽略参数)。
您可以:
using
声明b.Foo::stuff(3);
。注意:
main()
必须返回int
。#include <iostream>
class Foo
{
public:
int a;
void stuff(int a){ std::cout << a << std::endl; }
};
class Bar : public Foo
{
public:
using Foo::stuff;
protected:
void stuff() { std::cout << "hello world"; }
};
int main()
{
Bar b;
b.stuff(3);
}
或者:
int main()
{
Bar b;
b.Foo::stuff(3);
}
答案 1 :(得分:4)
在C ++中,当基类中的一个函数与派生类中的一个函数同名时,可以发生名称隐藏。
函数调用过程的阶段
只要在派生类Bar
中找到名称,名称查找就会停止查找其他名称。因此,Bar::stuff()
会隐藏stuff
中名称为Foo
的任何函数。
在名称查找过程之后,
stuff(int)
中没有Bar
。stuff()
没有int
参数,访问控制也会失败,因为stuff()
受到保护。答案 2 :(得分:4)
查找名称stuff
时,Bar
中的名称首先找到。找到后,将检查访问权限。由于Bar::stuff
受到保护,因此您无法在main
中使用它。
从草案标准:
10.2会员名称查找[class.member.lookup]
1成员名称查找确定类范围(3.3.7)中名称( id-expression )的含义。名称查找可能会导致歧义,在这种情况下,程序格式不正确。对于 id-expression ,名称查找从
this
的类范围开始;对于 qualified-id ,名称查找从 nestedname-specifier 的范围开始。名称查找在访问控制之前进行(3.4,第11条)。
答案 3 :(得分:0)
b.Foo::stuff(3);
或者,你可以做一个技巧来访问任何受保护的:)
void main()
{
Bar b;
class BarAccess : public Bar { friend void main(); }
BarAccess * ba = reinterpret_cast<BarAccess *>(&b);
ba->stuff(3);
ba->stuff();
}