Использование 'override' для функции, которая была объявлена ​​с использованием 'typedef' - PullRequest
0 голосов
/ 31 августа 2018

C ++ 11 ввел спецификатор 'override' для функций, и я считаю его полезным, поскольку он явно указывает на то, что виртуальная функция переопределяется. Однако я не могу заставить его работать для функции, которая была объявлена ​​с использованием typedef.

Я понимаю, что "переопределение" - это не ключевое слово, это как-то связано с этим?

Следующий код иллюстрирует мою точку зрения:

#include <iostream>

typedef char ReturnsChar();

class Basic
{
    public:
    virtual char get_a();
    virtual ReturnsChar get_z;
};

char Basic::get_a() { return 'a'; }
char Basic::get_z() { return 'z'; }

class Capitalized : public Basic
{
    public:
    // Can override explicitly if I use the normal definition
    char get_a() override;

    // Compiles if I use the typedef but not 'override'
    ReturnsChar get_z;

    // Will not compile, but would like to do this
    //ReturnsChar get_z override; 

};

char Capitalized::get_a() { return 'A'; }
char Capitalized::get_z() { return 'Z'; }

int main()
{
    Basic foo;
    Capitalized bar;

    std::cout << foo.get_a() << std::endl; // a
    std::cout << foo.get_z() << std::endl; // z
    std::cout << bar.get_a() << std::endl; // A
    std::cout << bar.get_z() << std::endl; // Z
}

Я использую GNU g ++ 8.2.0 и выдает ошибку

error: expected ';' at end of member declaration
ReturnsChar get_z override;
            ^~~~~
                      ;
error: ‘override’ does not name a type; did you mean ‘ctermid’?
     ReturnsChar get_z override;
                       ^~~~~~~~
                       ctermid

РЕДАКТИРОВАТЬ: Что касается комментариев, я понимаю, что этот стиль неясен. Меня больше интересует, почему это не скомпилируется и что именно делает переопределение (особенно потому, что это не ключевое слово). Кроме того, я чувствую, что функции определения типов могут быть понятны в некоторых случаях, скажем:

void (*foo(int x, void (*f)(int)))(int);

Сложно читать, особенно если часто появляется. Я могу просто определить это как «UpdateAddressFunction», а затем мысленно представить каждую функцию этого типа как нечто, «обновляющее адрес».

1 Ответ

0 голосов
/ 31 августа 2018

Я понимаю, что "переопределение" не является ключевым словом, имеет ли это какое-то отношение к этому?

Имеется: override распознается только в нескольких конкретных контекстах и ​​в противном случае доступно как имя для обычного использования. Тем не менее, я считаю, что это ошибка компилятора, и это один контекст, в котором компилятор должен распознать его в его особом значении.

Соответствующее грамматическое произведение для этого

[class.mem]

член-описатель:
описатель virt-specier-seq opt pure-спецификатор opt

Для этого не требуется, чтобы virt-specier-seq появлялся только в объявлении, содержащем параметры. Единственное подобное требование указано ниже:

[class.mem] P8:

A virt-specier-seq должен появляться только в объявлении виртуальной функции-члена (10.3).

В вашем случае объявление является одной из виртуальных функций-членов. Я считаю, что override следует принять здесь.

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