在下列情况下,请明确解释方法解析规则。我有一个想法,基于代码的行为,但希望澄清。
基于“调用对象的常量确定将调用哪个版本的MyArray :: Get(),从而确定调用者是否获得了一个可以操作或仅观察私有数据的引用这两个方法在技术上有不同的签名,因为它们的“this”指针有不同的类型,允许编译器从“wikipedia const correctness中选择正确的一个,我会得出结论,我的例子应该是的情况方法重载,不方法重写(因为const方法和非const方法有两个不同的签名)。
class Base
{
public:
void test()
{ std::cout << "nonconst call" << std::endl; }
};
class Child : public Base
{
public:
void test() const
{
std::cout << "const call" << std::endl;
Child * nonConstThis = const_cast<Child * >(this);
Base * nonConstBase = dynamic_cast<Base * >(nonConstThis);
// This call leads to infinite recursion by calling
// "void Child::test() const", which implies that
// a "Child *" will resolve to calling a const Child function
// before calling a non-const Base function.
//nonConstThis->test();
// This will call "void Base::test()"
nonConstBase->test();
}
};
void main()
{
Child * child = new Child;
child->test();
}
答案 0 :(得分:3)
它实际上是方法隐藏,而不是重载。
在派生类中创建具有相同名称的方法时,基类版本将不再可见。
struct A
{
void foo() {}
};
struct B : public A
{
void foo(int x) {}
};
B b;
b.foo(); //error
我假设您希望B::foo()
存在,但是,正如您所看到的,它没有。所以没有,不是cv-qualifiers(const
)或参数会影响这一点。
在您的情况下,名称未解析,因为它与const
有关,但是因为您在test
类型的对象上调用了Child
。然后,您在Base::test()
类型的对象上调用Base
,就像下面的代码一样:
((A)b).foo();
答案 1 :(得分:3)
您对过载名称解析在C ++中的工作方式感到磕磕绊绊。基类中的“test”函数变为“隐藏”(称为名称隐藏)。在寻找合适的函数来调用时,编译器首先查找派生类,看到匹配,然后停止查找。 This answer has a good description as to why
您可以使用using声明查看基类,如下所示:
class Child : public Base
{
public:
using Base::test;
这将告诉编译器也在Base中查找测试。