Я недавно обнаружил использование using
импортировать функцию базового класса в пространство имен производного класса (когда оно скрыто). Я пытался использовать его для импорта функции из базового класса в качестве реализации функции в производном классе:
class A {
public:
virtual void foo() = 0;
};
class B {
public:
void foo() {
}
};
class C : public A, public B {
public:
using B::foo;
};int main()
{
C c;
}
Это не скомпилируется как A::foo()
это чисто виртуальная функция в C
, Я надеялся что using B::foo;
сделает реализацию foo()
, Почему не так?
У вас есть два разные функции: A::foo()
а также B::foo()
, Хотя они имеют одно и то же безоговорочное имя, они не связанные с. B::foo()
не может и не может переопределить A::foo()
так как B
не подкласс A
,
C
наследует обе функции от A
а также B
, Вы используете публичное наследование для обоих базовых классов, поэтому A::foo()
а также B::foo()
являются уже видно в C
(обратите внимание, что вам нужно квалифицированное имя для вызова функций, чтобы избежать неоднозначности).
Так что ваше объявление об использовании фактически не имеет никакого эффекта.
Объявление использования, когда используется внутри класса, имеет отношение к перегрузка, но это не имеет ничего общего с переопределение. Это очень разные понятия.
перегрузка о наличии разных функций с одинаковым именем, но разными наборами аргументов.
Переопределение о полиморфизме, то есть о различных реализациях метода базового класса в производных классах.
Объявление using вводит имя функции из базового класса в производный класс, где это имя будет скрыто другой функцией с таким же именем но разные аргументы. Например:
class X
{
public:
void func() {}
};
class Y : public X
{
public:
void func(int arg) {}
};
Y::func
не переопределяет X::func
, поскольку его аргументы разные. Кроме того, это также шкуры имя func
из базового класса, поэтому он может быть вызван только через определенное имя, например:
X x;
x.func(); // ok
Y y;
y.func(1); // ok, Y::func called
y.func(); // error, base-class name func is hidden by local name
y.X::func(); // ok, qualified name, X::func called
В этом случае объявление using вводит имя из базового класса в производный класс, делая func
вызываемый без уточнения имени:
class Y : public X
{
public:
using X::func;
void func(int arg) {}
};
// ...
Y y;
y.func(); // ok, X::func called
using
в C ++ имеет другое значение и обозначает, что вы хотели бы иметь возможность доступа к функции / объекту в другом Пространство имен без ввода имени пространства имен в явном виде. Это не имеет ничего общего с переопределением.