используя объявление в определении класса - PullRequest
3 голосов
/ 31 мая 2019

Я обнаружил, что ключевое слово 'using' может использоваться в определении класса. в соответствии с https://en.cppreference.com/w/cpp/language/using_declaration, используется для функции-члена следующим образом:

Если имя является именем перегруженной функции-члена базы класс, представлены все функции-члены базового класса с этим именем. Если у производного класса уже есть член с тем же именем, список параметров и квалификации, производный член класса скрывает или переопределяет (не конфликтует) член, который вводится из базовый класс.

пример кода выглядит следующим образом:

#include <iostream>
struct B {
    virtual void f(int) { std::cout << "B::f\n"; }
    void g(char)        { std::cout << "B::g\n"; }
    void h(int)         { std::cout << "B::h\n"; }
 protected:
    int m; // B::m is protected
    typedef int value_type;
};

struct D : B {
    using B::m; // D::m is public
    using B::value_type; // D::value_type is public

    using B::f;
    void f(int) { std::cout << "D::f\n"; } // D::f(int) overrides     B::f(int)
    using B::g;
    void g(int) { std::cout << "D::g\n"; } // both g(int) and g(char) are visible
                                       // as members of D
    using B::h;
    void h(int) { std::cout << "D::h\n"; } // D::h(int) hides B::h(int)
};

int main()
{
    D d;
    B& b = d;

//    b.m = 2; // error, B::m is protected
    d.m = 1; // protected B::m is accessible as public D::m
    b.f(1); // calls derived f()
    d.f(1); // calls derived f()
    d.g(1); // calls derived g(int)
    d.g('a'); // calls base g(char)
    b.h(1); // calls base h()
    d.h(1); // calls derived h()
}

Из приведенного выше кода я не уверен, в чем разница, например

using B::f;
void f(int)

и

virtual void f(int)

Есть ли определенная разница в использовании ключевого слова using для переопределения функции-члена класса?

1 Ответ

2 голосов
/ 31 мая 2019

Формулировка из этой статьи вызывает сожаление.Они пытались исправить это с помощью скобок, но…

Это не имеет ничего общего с переопределением виртуальной функции.

Два приведенных вами примера различны и не связаны.

Один вводит в область действия базовый класс f, затем отбрасывает его и вводит новую функцию D::f.(Это не будет virtual, если B::f уже было, согласно нормальным правилам).

Другой объявляет virtual D::f.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...