0

我的基本问题是为什么名称隐藏在返回类型和参数列表都更改时不适用。请参考下面的样片。

// Example program
#include <iostream>
#include <string>
using namespace std;

class base {
public:
    int f() const { cout <<"I am base void version. "<<endl; return 1;}
    int f(string) const { cout <<"I am base string version. "<<endl; return        1;}
};

class Derived1 : public base {
public:
    int f() const {
        cout << "Derived1::f()\n";
        return 2;
    }
};

class Derived2 : public base {
public:
    int f(int) const {
        cout << "Derived2::f()\n";
        return 3;
    }
};

class Derived3 : public base {
public:
    void f(int) const {
        cout << "Derived3::f()\n";
    }
};


int main()
{
    string s("hello");
    Derived1 d1;
    int x = d1.f();
 //d1.f(s); // string version hidden

   Derived2 d2;
   //x = d2.f(); // f() version hidden
    x = d2.f(1);

    Derived3 d3;
    d3.f(1); // No name hiding
 }

输出 :

Derived1::f()

Derived2::f()

Derived3::f()

在上述程序中

a) 为什么 Derived2 对象不隐藏字符串版本?

b) 为什么当返回类型和参数都匹配时名称隐藏不适用?

有关“名称隐藏在编译器级别如何工作”的任何链接或参考?很有用。

谢谢你。

4

2 回答 2

2

来自 Bjarne Stroustrup关于此主题的常见问题解答

为什么重载对派生类不起作用?

该问题(在许多变体中)通常由以下示例提示:

#include<iostream>
using namespace std;

class B {
public:
  int f(int i) { cout << "f(int): "; return i+1; }
  // ...
};

class D : public B {
public:
  double f(double d) { cout << "f(double): "; return d+1.3; }
  // ...
};

int main()
{
  D* pd = new D;

  cout << pd->f(2) << '\n';
  cout << pd->f(2.3) << '\n';
}

这将产生:

  f(double): 3.3
  f(double): 3.6

而不是

  f(int): 3
  f(double): 3.6

有些人(错误地)猜到了。

using base::f;您可以通过添加到派生类来修改问题中的程序以使隐藏的重载可用:

#include <iostream>
#include <string>
using namespace std;

class base {
public:
    int f() const { cout <<"I am base int version. "<<endl; return 1; }
    int f(string) const { cout <<"I am base string version. "<<endl; return        1; }
};

class Derived1 : public base {
public:
    using base::f;
    int f() const
    {
        cout << "Derived1::f()\n";
        return 2;
    }
};

class Derived2 : public base {
public:
    using base::f;
    int f(int) const 
    {
        cout << "Derived2::f()\n";
        return 3;
    }
};

class Derived3 : public base {
public:

    void f(int) const
    {
        cout << "Derived3::f()\n";
    }
};


int main()
{
    string s("hello");
    Derived1 d1;
    int x = d1.f();
    d1.f(s); // string version hidden

    Derived2 d2;
    x = d2.f(); // f() version hidden
    x = d2.f(1);

    Derived3 d3;
    d3.f(1); // No name hiding
}

那么输出是:

Derived1::f()
I am base string version.
I am base int version.
Derived2::f()
Derived3::f()
于 2016-04-26T02:22:46.020 回答
0

Name Hiding - 如果在派生类的成员函数中被赋予了新的定义,有两种可能

  1. 签名和返回类型保持不变

    ---函数重定义(针对普通成员函数)

    ---函数覆盖(对于虚成员函数)

  2. 签名和返回类型更改 ---名称隐藏

    • 如果一个函数在派生类中被赋予了新的定义,那么所有其他版本都会自动隐藏在派生类中

    • 跨范围无法重载

于 2018-08-10T13:09:45.917 回答