Доступ к скрытым функциям из базовых классов с разными сигнатурами
У нас есть:
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' противоречит предыдущему объявлению использования
В любом случае, подумайте дважды, что вы делаете.
Вам нужна функция, которая в зависимости от количества / типа аргументов она вызывает для члена другого базового класса? Я не могу представить себе множество ситуаций, в которых это имеет смысл.
--------------Заключение---------------
- Подумайте дважды о том, что вы делаете. Методы сокрытия обычно не годятся.
- В первом примере клиенты могут использовать явные вызовы (они смогут получить доступ ко всем публичным участникам)
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)
, - Вы можете создавать нужные вам функции, как вы указали (нет ничего проще), но помните, что клиенты могут по-прежнему вызывать вас базовые функции!