Доступ к скрытым функциям из базовых классов с разными сигнатурами

У нас есть:

class A {
public:
    int f();
    int f(int);
  //...
};
class B {
public:
    int f();
    int f(int);
  //...
};
class AB : public A, public B {
public:
    long f(double, double);
  //...
};

A::f(), A::f(int), B::f(), B::f(int) теперь скрыты в class ABи я хочу использовать только A::f() а также B::f(int) как будто они не были спрятаны

AB ab;
ab.f();  // ab.A::f()
ab.f(1); // ab.B::f(1)

Есть ли более простой способ добиться этого, чем написать следующий код?

class AB : public A, public B {
public:
  //...
    int f() {return A::f();}
    int f(int x) {return B::f(x);}
};

Я думал о using ключевое слово, но оно не различает методы с одинаковыми именами и разными сигнатурами.

1 ответ

Решение

Единственный способ - объявить их и вызвать функцию базового класса, которую вы хотите, как вы написали.

Вы могли бы подумать об использовании каким-то странным способом "использования" ex: using A::f; но вы наследуете все сигнатуры функций с одинаковыми и не можете указать одну.

В объявлении класса AB есть:

  • Только с наследством

Вы получили интерфейс и реализацию от обоих базовых классов, у вас будет ошибка при вызове метода, который является общим для них обоих (Примечание! Даже если подпись не совпадает). theABVar.A::f(); дам тебе:

Ошибка:"запрос на член 'f' неоднозначен"

Но вы можете решить это с theABVar.A::f();(разве это не круто?:D)

  • Когда вы добавляете метод с тем же именем, что в обоих базовых классах

Члены базовых классов скрыты, поэтому вызов метода больше не является двусмысленным.
Но чтобы вызвать метод в базовом классе, вы должны сделать то же самое, что и раньше.

theABVar.f(); дам тебе

Ettor: нет соответствующей функции для вызова 'AB::f()'

  • Когда вы попытаетесь использовать "использование" для функций базового класса, вы получите время компиляции, даже если вы не используете функцию:

    используя A::f; используя B::f;

использование объявления 'using B::f' противоречит предыдущему объявлению использования

В любом случае, подумайте дважды, что вы делаете.
Вам нужна функция, которая в зависимости от количества / типа аргументов она вызывает для члена другого базового класса? Я не могу представить себе множество ситуаций, в которых это имеет смысл.

--------------Заключение---------------

  1. Подумайте дважды о том, что вы делаете. Методы сокрытия обычно не годятся.
  2. В первом примере клиенты могут использовать явные вызовы (они смогут получить доступ ко всем публичным участникам) theABVar.A::f(), theABVar.A::f(3), theABVar.B::f(), theABVar.B::f(3), theABVar.AB::f(3.0,3.0) а также theABVar.f(3.0,3.0),
  3. Вы можете создавать нужные вам функции, как вы указали (нет ничего проще), но помните, что клиенты могут по-прежнему вызывать вас базовые функции!
Другие вопросы по тегам