1

明确解释以下案例中的方法解析规则。我有一个想法,基于代码的行为,但想澄清一下。

基于“调用对象的 const-ness 确定将调用哪个版本的 MyArray::Get() ,从而确定调用者是否被给予一个引用,他可以使用该引用来操作或仅观察对象中的私有数据。这两种方法在技术上具有不同的签名,因为它们的“this”指针具有不同的类型,允许编译器从维基百科 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();
}
4

2 回答 2

3

它实际上是方法隐藏,而不是重载。

在派生类中创建同名方法时,基类版本不再可见。

struct A
{
    void foo() {}
};

struct B : public A
{
    void foo(int x) {}
};

B b;
b.foo(); //error

我假设您希望B::foo()存在,但是,正如您所看到的,它不存在。所以没有什么,不是 cv-qualifiers ( const) 或参数会影响这一点。

在您的情况下,名称未解析,因为它与 相关const,但因为您正在调用testtype 的对象Child。然后你调用Base::test()一个类型的对象Base,就像下面的例子一样:

((A)b).foo();
于 2012-03-12T20:29:46.460 回答
3

您对重载名称解析在 C++ 中的工作方式感到困惑。基类中的函数“test”变为“隐藏”(称为名称隐藏)。在寻找合适的函数来调用时,编译器首先在派生类中查找,找到匹配项,然后停止查找。这个答案对为什么有很好的描述

您可以使用 using 声明来查看基类,如下所示:

class Child : public Base
{
public:
    using Base::test;

这将告诉编译器也在 Base 中进行测试。

于 2012-03-12T20:34:19.183 回答