Используете ли вы спецификатор virtual при перекрытии функции:
class B {
virtual void f();
};
class D : public B {
virtualvoid f(); // <- здесь
};
Если последовательно использовать virtual в этом случае, то с первого взгляда, не просматривая базовые классы можно отличить виртуальные функции от невиртуальных; но не так удобно отличать первое объявление виртуальной функции от объявлений перекрывающих его. Если не использовать virtual, то наоборот. Поэтому с точки зрения самодокументирования программы счет 1:1.
А вот если функции B::f и D::f по ошибке получают разные имена, ошибку эту можно скорее заметить, если virtual при перекрытии не используется; потому-что функция в производном классе перестает быть виртуальной, и если в программе имеется производный от D класс E, ошибка будет проявляться и в случаях, когда объекты класса E используются как объекты класса D, а не только когда объекты класса D используются как объекты класса B.
То есть мое предварительное мнение таково, что использовать спецификатор virtual при перекрытии функции не нужно. Тем более без него короче.
Если это соц опрос то ответ ДА, всегда.
I>но не так удобно отличать первое объявление виртуальной функции от объявлений перекрывающих его.
А в чем для вас принципиальная разница ?
I>То есть мое предварительное мнение таково, что использовать спецификатор virtual при перекрытии функции не нужно. Тем более без него короче.Вот это в программировании имхо вобще не аргумент!
Вобщем согласен с Джефри Элджером, который сказал, что если этот модификатор не писать каждый раз при объявлении функции, по всей цепочке, то однажды ваши коллеги не разобравшись как работает программа устроят погром в офисе
Re[2]: Спецификатор virtual при перекрытии функции
сорри I>То есть мое предварительное мнение таково, что использовать спецификатор virtual при перекрытии функции не нужно. Тем более без него короче.Вот это в программировании имхо вобще не аргумент!
Читать как : I>То есть мое предварительное мнение таково, что использовать спецификатор virtual при перекрытии функции не нужно.
Тем более без него короче.Вот это в программировании имхо вобще не аргумент!
Re: Спецификатор virtual при перекрытии функции
От:
Аноним
Дата:
31.08.07 06:49
Оценка:
Здравствуйте, igna, Вы писали:
I>То есть мое предварительное мнение таково, что использовать спецификатор virtual при перекрытии функции не нужно. Тем более без него короче.
Мое с точностью до наоборот
Чтобы было видно, что эта функция переопределена\может быть переопределена
P.S. Ключевого слова override не хватает
Re[2]: Спецификатор virtual при перекрытии функции
Здравствуйте, dip_2000, Вы писали:
_>Вобщем согласен с Джефри Элджером, который сказал, что если этот модификатор не писать каждый раз при объявлении функции, по всей цепочке, то однажды ваши коллеги не разобравшись как работает программа устроят погром в офисе
Здравствуйте, Аноним, Вы писали:
I>>То есть мое предварительное мнение таково, что использовать спецификатор virtual при перекрытии функции не нужно. Тем более без него короче. А>Мое с точностью до наоборот
А>Чтобы было видно, что эта функция переопределена\может быть переопределена
Страуструп в своей книге не использует virtual при перекрытии.
Re[2]: Спецификатор virtual при перекрытии функции
Здравствуйте, Roman Odaisky, Вы писали:
RO>Если наследоваться только от интерфейсов («make non-leaf classes abstract») и использовать NVI, таких проблем не будет.
Перекрывать функции придется все-равно.
Re[3]: Спецификатор virtual при перекрытии функции
От:
Аноним
Дата:
31.08.07 07:12
Оценка:
Здравствуйте, igna, Вы писали:
А>>Чтобы было видно, что эта функция переопределена\может быть переопределена I>Страуструп в своей книге не использует virtual при перекрытии.
Это не аргумент. В книге обычно примеры упрощены.
P.S. Страуструп вроде уже доктор\проффесор, а ты кто(да и я)? В общем, не надо тупо все копировать
Re[4]: Спецификатор virtual при перекрытии функции
Здравствуйте, igna, Вы писали:
I>Здравствуйте, dip_2000, Вы писали:
_>>Вобщем согласен с Джефри Элджером, который сказал, что если этот модификатор не писать каждый раз при объявлении функции, по всей цепочке, то однажды ваши коллеги не разобравшись как работает программа устроят погром в офисе
I>Это он где сказал?
В своей книге С++ for real programmers
Re[3]: Спецификатор virtual при перекрытии функции
Здравствуйте, igna, Вы писали:
RO>>Если наследоваться только от интерфейсов («make non-leaf classes abstract») и использовать NVI, таких проблем не будет.
I>Перекрывать функции придется все равно.
Воистину придется, но тогда неперекрытые виртуальные функции будут вызывать ошибки компилятора.
Здравствуйте, igna, Вы писали:
I>Используете ли вы спецификатор virtual при перекрытии функции:
I>
I>class B {
I> virtual void f();
I>};
I>class D : public B {
I> virtualvoid f(); // <- здесь
I>};
I>
I>Если последовательно использовать virtual в этом случае, то с первого взгляда, не просматривая базовые классы можно отличить виртуальные функции от невиртуальных; но не так удобно отличать первое объявление виртуальной функции от объявлений перекрывающих его. Если не использовать virtual, то наоборот. Поэтому с точки зрения самодокументирования программы счет 1:1.
I>А вот если функции B::f и D::f по ошибке получают разные имена, ошибку эту можно скорее заметить, если virtual при перекрытии не используется; потому-что функция в производном классе перестает быть виртуальной, и если в программе имеется производный от D класс E, ошибка будет проявляться и в случаях, когда объекты класса E используются как объекты класса D, а не только когда объекты класса D используются как объекты класса B.
I>То есть мое предварительное мнение таково, что использовать спецификатор virtual при перекрытии функции не нужно. Тем более без него короче.
повторно не пишу virtual.
Стараюсь всегда писать override тогда компилятор сам за мною следит.
Здравствуйте, igna, Вы писали:
I>Если последовательно использовать virtual в этом случае, то с первого взгляда, не просматривая базовые классы можно отличить виртуальные функции от невиртуальных; но не так удобно отличать первое объявление виртуальной функции от объявлений перекрывающих его/
ИМХО, возможность слету отличать виртуальные функции от невиртуальных имеет бОльшую ценность. А когда вообще может оказаться полезным знание о том, объявлена ли функция впервые или перекрывается?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: Спецификатор virtual при перекрытии функции
> А>P.S. Страуструп вроде уже доктор\проффесор, а ты кто(да и я)? В общем, не надо тупо все копировать > > И Саттер профффесор. И Александреску вроде тоже.
Александреску — аспирантишко
> Порекомендуй книжку написанную не профффесором, а настоящим умственным пролетарием.
С++ for real programmers? Чиста от пролетария для пролетариев
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
igna пишет: > Если последовательно использовать virtual в этом случае, то с первого > взгляда, не просматривая базовые классы можно отличить виртуальные
Ну пишите вместо этого в дочернем классе override.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Спецификатор virtual при перекрытии функции
rg45 пишет: > ИМХО, возможность слету отличать виртуальные функции от невиртуальных > имеет бОльшую ценность. А когда вообще может оказаться полезным знание о > том, объявлена ли функция впервые или перекрывается?
Да никакой ценности IMHO
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Спецификатор virtual при перекрытии функции
Здравствуйте, rg45, Вы писали:
R>ИМХО, возможность слету отличать виртуальные функции от невиртуальных имеет бОльшую ценность. А когда вообще может оказаться полезным знание о том, объявлена ли функция впервые или перекрывается?
Не возражаю, но хочу понять почему ни Страуструп, ни Саттер virtual при перекрытии не используют. Просто хотелось бы знать пару аргументов в пользу их стиля.
Re[2]: Спецификатор virtual при перекрытии функции
Здравствуйте, <Аноним>, Вы писали:
А>P.S. Ключевого слова override не хватает
В VC8 есть.
Видимо, авторы компилятора решили не париться с разделением C++98 и C++CLI, и часть синтаксиса (не требующая дотнетовских фишек для реализации) из последнего доступна в первом.
Очень удобно!
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[3]: Спецификатор virtual при перекрытии функции
Здравствуйте, igna, Вы писали:
I>Здравствуйте, IROV.., Вы писали:
IRO>>Стараюсь всегда писать override тогда компилятор сам за мною следит.
I>В стандарте никакого override нет.
MSVC8.0 держит, и пока работаю на нем, буду пользоватся им, и ждать пополнения в стандарте такой фичи, очень хорошей!
для переносимости есть
# define override
я не волшебник, я только учусь!
Re[3]: Спецификатор virtual при перекрытии функции
Здравствуйте, igna, Вы писали:
I>Здравствуйте, Кодт, Вы писали:
К>>В VC8 есть.
I>У меня в VC++ 2005 Express нет, то есть override подсвечивается, но не компилируется. Какие-нибудь установки?
Так, на всякий случай, override ставишь там где нужно? Нужно после объявления функции:
void foo() override
{
}
З.Ы. Я, все-таки, это использовать не стал бы.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: Спецификатор virtual при перекрытии функции
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, <Аноним>, Вы писали:
А>>P.S. Ключевого слова override не хватает
К>В VC8 есть. К>Видимо, авторы компилятора решили не париться с разделением C++98 и C++CLI, и часть синтаксиса (не требующая дотнетовских фишек для реализации) из последнего доступна в первом. К>Очень удобно!
Типа так:
#if _MSC_VER < 1400
#define override
#endif
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: Спецификатор virtual при перекрытии функции
Здравствуйте, igna, Вы писали:
MZ>>Ну пишите вместо этого в дочернем классе override. I>Это какого компилятора расширение?
Ну можешь определить
#define override virtual
а иногда собирать проект с override переопределённым в ничто.
Хотя, ИМХО, это не особо нужно, так как вроде компиляторы умеют в подозрительном случае выдавать предупреждения.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Спецификатор virtual при перекрытии функции
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, igna, Вы писали:
MZ>>>Ну пишите вместо этого в дочернем классе override. I>>Это какого компилятора расширение?
E>Ну можешь определить
#define override virtual
а иногда собирать проект с override переопределённым в ничто. E>Хотя, ИМХО, это не особо нужно, так как вроде компиляторы умеют в подозрительном случае выдавать предупреждения.
Ыыыыыыыыыыыыыыыыыы!!!!
void foo() virtual
у тебя что это скомпилится?
я не волшебник, я только учусь!
Re[5]: Спецификатор virtual при перекрытии функции
Здравствуйте, IROV.., Вы писали:
IRO>у тебя что это скомпилится?
А ты пиши так: override void foo()
Правда будет несовместимо с хаком от MSVC, ну можешь тогда другое слово выбрать, скажем implement
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Спецификатор virtual при перекрытии функции
Здравствуйте, igna, Вы писали:
I>Или overtual. А то еще с каким-нибудь хаком несовместимо будет.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: Спецификатор virtual при перекрытии функции
> S>С++ for real programmers? Чиста от пролетария для пролетариев > > Сейчас в амазоне посмотрел, этой книге скоро 10 лет. Там хоть шаблоны есть?
Насколько помню, есть. Я эту книжку не хвалю (для real programmers она ничего так, но спорных вещей там выше крыши.), просто не одни профессора книжки пишут.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Стараюсь писать, т.к. в этом случае ясно, что она может быть перекрыта другой функцией, либо может перекрывать сама другую.
Намного удобнее, чем искать описание базовых классов.
ИМХО, возможность при перекрытии функций опускать слово virtual — удобство весьма сомнительное, лучше бы его не было вовсе. Смотришь на функцию — если virtual есть, значит виртуальная, а если нет — лезь вверх по иерархии классов и выясняй.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[5]: Спецификатор virtual при перекрытии функции
Здравствуйте, igna, Вы писали:
RO>>Воистину придется, но тогда неперекрытые виртуальные функции будут вызывать ошибки компилятора.
I>Я ведь о том, спецификатор virtual писать или нет, а ты о чем?
Я о том, что в грамотно спроектированных классах вот этой проблемы вообще нет:
А вот если функции B::f и D::f по ошибке получают разные имена, ошибку эту можно скорее заметить, если virtual при перекрытии не используется; потому что функция в производном классе перестает быть виртуальной
До последнего не верил в пирамиду Лебедева.
Re[3]: Спецификатор virtual при перекрытии функции
Здравствуйте, igna, Вы писали:
I>Не возражаю, но хочу понять почему ни Страуструп, ни Саттер virtual при перекрытии не используют. Просто хотелось бы знать пару аргументов в пользу их стиля.
Возможный вариант — на virtual в этом случае полагаться опасно:
class Interface
{
. . .
virtual void doSomething() = 0;
. . .
};
/** @author SensibleDeveloper */class Implementation1: public Interface
{
. . .
virtual void doSomething(); // OK, это реализация виртуальной функции (потому что не = 0 и не в интерфейсе)
. . .
};
/** @author CarelessDeveloper */class Implementation2: public Interface
{
. . .
void doSomething(); // а это, надо полагать, обычная невиртуальная функция?
. . .
};
Для документированности можно еще что сделать:
#define VIRTUALS private
class Implementation: public Interface
{
public:
Interface();
. . .
VIRTUALS:
void doSomething();
. . .
private:
Member member_;
. . .
};
До последнего не верил в пирамиду Лебедева.
Re[2]: Спецификатор virtual при перекрытии функции
> ИМХО, возможность при перекрытии функций опускать слово virtual — удобство весьма сомнительное, лучше бы его не было вовсе. Смотришь на функцию — если virtual есть, значит виртуальная, а если нет — лезь вверх по иерархии классов и выясняй.
А какой толк от знания, что функция в наследнике виртуальная? Этого все равно не достаточно. Важно знать, что она виртуальная и переопределяет какую-то конкретную функцию базового класса. Так что в любом случае — лезь вверх по иерархии классов и выясняй. Вот если бы было отдельное ключевое слово override или что-нибудь подобное — другое дело.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[3]: Спецификатор virtual при перекрытии функции
Здравствуйте, Sergey, Вы писали:
S>...Вот если бы было отдельное ключевое слово override или что-нибудь подобное — другое дело.
Ну так какое дело? Заведи такое слово, если оно тебе реально нужно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Спецификатор virtual при перекрытии функции
> S>...Вот если бы было отдельное ключевое слово override или что-нибудь подобное — другое дело. > > Ну так какое дело? Заведи такое слово, если оно тебе реально нужно...
Это ты про VC? Вообще дело полезное и нужно, MS тут молодцы. Но в одиночку от такого спецификатора проку не очень много. Желательно бы еще чтобы он был обязателен к написанию. А чтобы его введение не поломало существующий код — чтобы он был обязателен к написанию при некоторых условиях, заданных в базовом классе. Конкретно хотелось бы следующее — если базовый класс объявлен со спецификаором explicit, то в его наследниках override для переопределения виртуальных функций обязателен. Сильно помогло бы при рефакторинге. Ну и заодно все конструкторы в классе и его наследниках чтоб по умолчанию становились explicit (а это уже вроде в C++0x обещают).
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[5]: Спецификатор virtual при перекрытии функции
Здравствуйте, Sergey, Вы писали:
S>...Ну и заодно все конструкторы в классе и его наследниках чтоб по умолчанию становились explicit (а это уже вроде в C++0x обещают).
Что, включая конструктор копии?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Спецификатор virtual при перекрытии функции
> S>...Ну и заодно все конструкторы в классе и его наследниках чтоб по умолчанию становились explicit (а это уже вроде в C++0x обещают). > > Что, включая конструктор копии?
Здравствуйте, rg45, Вы писали:
R>ИМХО, возможность при перекрытии функций опускать слово virtual — удобство весьма сомнительное, лучше бы его не было вовсе. Смотришь на функцию — если virtual есть, значит виртуальная, а если нет — лезь вверх по иерархии классов и выясняй.
Плохая идея перекрывать виртуальную функцию с реализацией в базовом классе. Если есть желание разместить часть реализации в базовом классе, то юзайте паттерн Шаблонный Метод или NVI. Перекрывайте только чисто виртуальные функции. Тогда непрозрачность перекрытия по иерархии отпадает.
Если держать себя в руках, то
virtual ... = 0; // первое объявление виртуальной функции
virtual ...; // даем реализацию виртуальной функции