#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 — Какой компилятор вы используете? Пожалуйста, убедитесь, что вы включили компилятор и его версию в вопрос. Еще многие пользователи пытаются дать вам рекомендации по компиляции программы с помощью имеющихся у них компиляторов.