Убедиться, что объявление метода унаследовано

#c

#c

Вопрос:

Как я могу защитить от случайного определения ненаследуемого метода, для которого предназначено унаследованное определение. Мне сказали, что есть уловка, чтобы выразить это, но никто не может вспомнить это.

Объяснение. У меня есть дерево классов: ‘Base’ <- ‘C’ <- ‘D’, ниже. Base определяет чисто виртуальную функцию. Функция переопределяется в C, затем в D. Но функция имеет очень длинный список аргументов.

Где-то в цепочке вывода в agrglist есть небольшая ошибка, которая делает D:: ненаследованным. Программа успешно компилируется. И во время выполнения вызывается неправильный метод.
Есть ли способ вызвать ошибку компиляции, когда метод не унаследован.

 #include <iostream>

class Base {
public:
    virtual void VeryLongFunctionName(int VeryLongArgumentList) = 0;
};
class C : public Base {
public:
    void VeryLongFunctionName(int VeryLongArgumentList) {
        std::cout << "C::n";
    }
};
class D : public C {
public:
    void VeryLongFunctionNane(int VeryLongArgumentList) { // typo is intentional. It's the point of the question.
        std::cout << "D::n";
    }
};

int main() {
    Base *p = new D;
    p->VeryLongFunctionName(0);
            // the intention is to print D::. But it prints C::.
            // How can we make compiler catch it.       
    return 0;
}
  

Комментарии:

1. p->VeryLongFunctionName(); даже не будет компилироваться.

2. @Prason: То, что вы считаете «опечаткой», является частью вопроса. Вопрос в том, как заставить компилятор перехватить ошибку. Но код компилируется и выполняется. Пожалуйста, перечитайте объяснение, если вам нужно.

3. @batbat: То, что вы считаете «опечаткой», является частью вопроса. Вопрос в том, как заставить компилятор перехватить ошибку. Но код компилируется и выполняется. Пожалуйста, перечитайте объяснение, если вам нужно

4. p->VeryLongFunctionName() является ошибкой, потому что вы не передаете его аргумент, int verylongargargumentlist .

5. @Andrey : Оно не компилируется. Проверьте это здесь

Ответ №1:

не совсем то, что вы просили, но я использовал эту форму, чтобы уменьшить вероятность человеческой ошибки:

 class t_very_long_argument_list {
public:
    t_very_long_argument_list(T1amp; argument1, const T2amp; argument2);
    /* ... */
    T1amp; argument1;
    const T2amp; argument2;
};

int C::VeryLongFunctionName(t_very_long_argument_listamp; arguments) {
    std::cout << "C::n";
}
  

Ответ №2:

Именно для этой цели в C 0x вводится override декоратор функции-члена, который уже реализован в VC 2005 и более поздних версиях: http://msdn.microsoft.com/en-us/library/41w3sh1c.aspx

В качестве альтернативы, VC допускает следующее (предположительно, зависящее от компилятора):

 #include <iostream>

class Base {
public:
    virtual void VeryLongFunctionName(int VeryLongArgumentList) = 0;
};

class C : public Base {
public:
    void Base::VeryLongFunctionName(int VeryLongArgumentList) {
        std::cout << "C::n";
    }
};

class D : public C {
public:
    void Base::VeryLongFunctionNane(int VeryLongArgumentList) {
    //   ^^^^^^ now causes a compilation error
        std::cout << "D::n";
    }
};
  

Комментарии:

1. Бинго. ‘переопределение’ — это оно. Жаль, что не в g … пока.

2. Base:: stuff не компилируется в g

3. @Andrey : Отредактировано, чтобы отразить, что Base:: материал специфичен для VC .

Ответ №3:

У вас ошибки компиляции —

  • int VeryLongFunctionName(int VeryLongArgumentList) предполагается, что оно возвращает, int чего не делает ни одно из определений метода.
  • int VeryLongFunctionName(int VeryLongArgumentList) предполагается, что должно быть получено int .

    p->VeryLongFunctionName(); // Ошибка

Исправив это, вы должны получить ожидаемые результаты. Проверьте результаты: http://ideone.com/wIpr9

Комментарии:

1. @Andrey — Какой компилятор вы используете? Пожалуйста, убедитесь, что вы включили компилятор и его версию в вопрос. Еще многие пользователи пытаются дать вам рекомендации по компиляции программы с помощью имеющихся у них компиляторов.