Здравствуйте, Videoman, Вы писали:
V>Тут да, неоднозначность получается. Тогда действительно можно указать virtual, показав, что мне всё равно что компилятор будет звать:
не все равно.
будет один IBase. это усложняет работу с поиском нужного метода, появляются доп смещения.
в общем, насколько понимаю, такие вызовы дороже обходятся (но это не точно)
ну и сама компиляция усложняется. деталей не помню но при виртуальном наследовании где-то идет комбинаторный взрыв и память расходуется в больших объемах.
по крайней мере раньше что-то вроде:
быстро ложило компилятор.
V>Только не понятно, что изменится в самом классе в таком случае, кроме подавления ошибки компилятора, при обращении к такому методу. Интересно...
все усложняется, поэтому плохо что в плюсах нет полноценных интерфейсов.
Здравствуйте, night beast, Вы писали:
NB>не все равно. NB>будет один IBase. это усложняет работу с поиском нужного метода, появляются доп смещения. NB>...
Здравый смысл по прежнему отказывается это понимать. Откуда там смещения, если нет данных? По сути речь идет о статической структуре таблиц виртуальных функций, причем только одного объекта — object. Или вы хотите сказать, что указатель на таблицу виртуальных функций и будет являться не явными данными всех классов ? Почему компилятор это не оптимизирует, если мне по сути без разницы через что вызывать?
Здравствуйте, Videoman, Вы писали:
NB>>не все равно. NB>>будет один IBase. это усложняет работу с поиском нужного метода, появляются доп смещения. NB>>...
V>Здравый смысл по прежнему отказывается это понимать. Откуда там смещения, если нет данных? По сути речь идет о статической структуре таблиц виртуальных функций, причем только одного объекта — object. Или вы хотите сказать, что указатель на таблицу виртуальных функций и будет являться не явными данными всех классов ?
да. как только ты добавляешь в класс виртуальную функцию у объекта (экземпляра класса) появляется указатель на таблицу виртуальных функций.
виртуальное наследование к этому добавляет доп. сложностей (сейчас, к сожалению, уже не найду статью с описанием внутренней реализации)
V> Почему компилятор это не оптимизирует, если мне по сути без разницы через что вызывать?
потому что компилятор во время компиляции не знает, какой метод будет вызван
V>В том-то и проблема, что не хочется конфликтов и головняка как отличить Person от интерфейса с таким же названием. Хочется типа такого:
Я придерживаюсь мнения, что это должно быть понятно из названия. Более конкретно (я так понимаю вы работаете с видео):
Stream — очевидно, что это абстрактный класс. VideoStream — тоже абстрактный класс. AvcStream — конкретный класс для реализации H.264/AVC. То есть по контексту и физической сути класса должно быть понятно, что есть что. ИМХО, всякие IStream тут излишни, т.к. понятно, что stream (поток) — это абстрактный поток.
Здравствуйте, Videoman, Вы писали:
V>В том-то и проблема, что не хочется конфликтов и головняка как отличить Person от интерфейса с таким же названием. Хочется типа такого:
Если у тебя person это и интерфейс, и конкретный класс, занчит у тебя что-то не правильно с твоими абстракциями.
Здравствуйте, Kernan, Вы писали:
K>Если у тебя person это и интерфейс, и конкретный класс, значит у тебя что-то не правильно с твоими абстракциями.
Это можно знать только задним числом, разобравшись в иерархии. Я привел пример просто как иллюстрацию, что в общем виде, взглянув на такое имя без контекста, не понятно, что это, реализация или интерфейс. Мой вопрос, кто как это обозначает или не обозначает, просто для обмена опытом.
Есть еще одна специфика, у себя я практически не использую интерфейсы в чистом виде. У меня не COM в общем понимании. Обычно интерфейсы появляются там, где без динамического полиморфизма ну уж совсем не обойтись, что бы в функцию можно было подсунуть любой внешний сторонний класс при необходимости. Типа такого:
namespace media
{
class sample : public i_sample
{
// ..
};
}
У меня самого в библиотеке класс почти всегда один и по сути это default implementationи и она всегда устраивает, а интерфейс может понадобиться для внешнего кода. Поэтому называть все классы default_something, просто из-за наличия интерфейса мне бы не хотелось.
Потом, выделять интерфейс в имени это не я придумал, так много где делают, например Microsoft и Google те же. Проблема в том, что у них другой стиль именования и он мне не подходит.
Здравствуйте, Videoman, Вы писали:
V>Еще есть какие-нибудь варианты?
Одна из самых понятных и универсальных нотаций, это простая С нотация основаная на snake case, в которой для обозначения типа используется суффикс _t:
clock_t
date_t
uuid_t
Подобный подход можно всретить даже в самом стандарте C и его стандартных библиотеках. Если продолжить эту идею, то для интерфейсов можно было бы использовать суффикc _i:
base_i
Второй очень понятный вариант — это классический pascal сase:
IBase
Наверное вот это и всё. Это два самых жизнеспособных варианта, только потому, что всё сразу понятно даже для абсолютно посторонних людей.
Не вижу никаких преимуществ аббревиатуры-префикса перед полными словами: window_base или WindowBase >> IWindow. Использование нормальных слов ближе к духу современного C++.
В целом проще всего следовать какому-то хорошо определенному стилю: std/boost или Qt.