Имя скрывается при изменении как возвращаемого типа, так и списка аргументов

Мой основной вопрос заключается в том, почему скрытие имени не применимо при изменении как возвращаемого типа, так и списка аргументов. Пожалуйста, обратитесь ниже образец образца.

// 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()

В вышеуказанной программе

а) Почему строковая версия не скрыта для объекта Derived2?

б) Почему скрытие имени не применимо, когда совпадают и возвращаемый тип, и аргумент?

Любые ссылки или ссылки на «как скрытие имен работает на уровне компилятора?» полезны

Спасибо.

0

Решение

От самого Бьярна Страуструпа FAQ по этой теме:

Почему перегрузка не работает для производных классов?

Этот вопрос (во многих вариациях) обычно задается примером, подобным этому:

#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()
2

Другие решения

Сокрытие имени
— Если в производном классе функция-член получает новое определение, есть две возможности

  1. Подпись и тип возврата остаются прежними

    Функция Redifinition (для обычных функций-членов)

    Переопределение функций (для виртуальных функций-членов)

  2. Подпись и тип возвращаемых изменений
    Сокрытие имени

    • Если функция получает новое определение в производном классе, все остальные версии автоматически скрываются в производном классе.

    • Перегрузка между областями невозможна

0

По вопросам рекламы [email protected]