Advanced: Тема повышенной сложности или важная.
vonrims
> Что ж. Выбор твой.
ну скажем у меня выбора нету. переписывать всерано ничего не буду - мне все-таки кушать хочется иногда, а переписывание кода к доходам не ведет.
> Для меня ценней написать один раз аггрегацию, чем много раз писать
> множественное наследование.
множественное наследование писать не надо - оно встроено в компилятор ;)
vonrims
> Да и монстр не особенно жирный вышел.
так или иначе, он монстр, и внедрение подобного - тяжело будет переносится проектом. факт. а включение его в проект изначально - тоже требует достаточных оснований. куча лишнего кода в проекте - источник ошибок, и соотвественно время разработки увеличивается, но я лично считаю что ЯВУ должен увеличивать сккорось разработки (и кстати абстрогировать от низкоуровневой реализации компилятора и генерируемого им кода, т.е. если скомпилилось - значит это корректо с точки зрения языка, т.е. программист может нарушить только логику, а когда для разбора проблемы требуется отладка на увровне asm-а - это фейл, а не компилятор)
Kloun
> что подразумевается под сущностью? IObject и IObjectModel - это одно сущность!
> это объект на локации.
если это одна сущность, то зачем она представлена двумя интерфейсами (это ещё нормально), при этом один порождён от другого?
> где там неэффективный код
измерьте скорость доступа к данным, скорость вызова методов - они идут через специальные обработчики,
которые постоянно меняют указатели или даже вызывают функции через функции для covariant return types, как вы и описали.
кроме того, sizeof(ObjectModelImp) = 3*sizeof(void*), при этом класс не содержит данных.
кроме этого, хотел бы отметить, что предложенный вариант не предполагает агрегацию,
вам просто необходимо в нужном классе реализовать функции get_object() и get_model(),
тело которых должно состоять из строки return this;
Kloun
> Вобщем почему-то все считают, что раз тема виртуального наследования темная
> мало изученная и непонятная, надо ее заменять костылями и решениями через зад
Наличие сабжа предполагает, что автор тоже не совсем в теме.
Я тут не для того, чтобы спорить или уговаривать.
Мой поинт в том, что есть гибгий механизм, который пишется один раз и про сложные иерархии объектов и связанные с ними грабли забывается.
Я использую этот подход не потому, что фанат велосипедов. Когда-то и в моём коде встречалось множественное наследование.
а вот вы мне объяснити вот что, как мне быть
есть в IObject RayIntersection()
RayIntersection по-разному реализуется в разных видах объектов.
Дмитрий Ясенев
> вам просто необходимо в нужном классе реализовать функции get_object() и
> get_model(),
ну это чтобы обойти баг. да я так и сделал. еще на 1ой странице написал вроде или на 2й
vonrims
> Наличие сабжа предполагает, что автор тоже не совсем в теме.
сабж описал - ошибка компилятора =)) почему это ошибка, а не особенность - пост 60
vonrims
> Мой поинт в том, что есть гибгий механизм, который пишется один раз и про
> сложные иерархии объектов и связанные с ними грабли забывается.
прокомментируй пожалуйста пост 63. твой поинт решает?
Kloun
> множественное наследование писать не надо - оно встроено в компилятор ;)
у тебя разветвлёная иерархия классов
каждый объект пишется заново
Kloun
> так или иначе, он монстр, и внедрение подобного - тяжело будет переносится
> проектом. факт. а включение его в проект изначально - тоже требует достаточных
> оснований. куча лишнего кода в проекте - источник ошибок, и соотвественно время
> разработки увеличивается
Пяток простых классов... что то ты не понял.
Каждому компоненту вместо интерфейса нужен простой базовый класс, который реализует всю логику аггрегации и запрос компонентов другого типа (как пример, QueryInterface в COM).
Объявление нового композитного объекта - typedef в одну строку, вместо нового класса.
Для меня оно ускорило разработку и внедрил запросто.
Kloun
> сабж описал - ошибка компилятора =)) почему это ошибка, а не особенность - пост
> 60
Я попытался объяснить почему это НЕ ошибка. Ты, похоже, не услышал.
Kloun
> прокомментируй пожалуйста пост 63. твой поинт решает?
Я не спорю... дал совет. Попытался рассказать почему именно так поступаю.
Дискутирую в защиту аггрегации чисто с целью совместно найти что-то более удобное. Уже скорее по инерции.
Тут не предлагается ничего кардинально нового, а я уже всё сказал.
vonrims
> Я попытался объяснить почему это НЕ ошибка. Ты, похоже, не услышал.
я понимаю почему эта ошибка происходит - иначебы я ее просто не нашел. а ты объяснил именно это. откуда она взялась. язык может меня защитить от этой ошибки - онже не дает мне переопределить метод так, чтобы вместо IObject возвращалась не ObjectImp, а скажем какойнить float - не дает, значит и тут не должен позволять тогда, раз есть грабли. (причем их возникновение = 100%, если мы определили метод в базовом классе, значит мы будем его использовать, и значит ошибка эта вылезет. сталобыть это недостаток компилятора - надо либо ругнуться на этапе компиляции, либо скомпилировать корректный код.
> Дискутирую в защиту аггрегации чисто с целью совместно найти что-то более
> удобное
а я зачем тут думаешь? по мне - раз грабли рядом, и стоит костыль, значит надо найти решение, такое, чтобы костыль можно было убрать, а то через пол-года я про него и забуду и обязательно споткнусь еще раз.
информация из поста 63, раньше не писал, просто не придавал значения - всех ньюансов в голове не удержать =(( темболее если они вписались в структуру идеально. а Дмитрий какраз напомнил.
Kloun
> ну это чтобы обойти баг. да я так и сделал. еще на 1ой странице написал вроде
> или на 2й
чтобы обойти баг, вам необходимо поменять порядок наследования, о чём я уже третий раз пишу :)
вот код:
struct IObject { virtual IObject* create() = 0; virtual void test() = 0; }; struct IObjectModel : virtual IObject { }; // ================ реализация struct ObjectImp : virtual IObject { virtual ObjectImp* create(); virtual void test() {} }; //struct ObjectModelImp : IObjectModel, ObjectImp { }; struct ObjectModelImp : ObjectImp, IObjectModel { }; // ----------- функция создания объекта ObjectImp* ObjectImp::create() { return new ObjectModelImp(); } // ================ пробуем int _tmain(int argc, _TCHAR* argv[]) { IObject* a = new ObjectModelImp(); IObject* b = a->create(); b->test(); ////// на этой строке мы уже никуда не улетаем return 0; }
я же предложил другой вариант, который до этого в этой ветке не встречал (SMG написал что-то аналогичное)
struct IModel; struct IObject { virtual IModel* get_model() = 0; virtual IObject* create() = 0; virtual void test() = 0; }; struct IModel { virtual IObject* get_object() = 0; }; struct ObjectImp : IObject { virtual ObjectImp* create(); virtual void test() {} }; struct ObjectModelImp : ObjectImp, IModel { virtual IModel* get_model() { return this;} virtual IObject* get_object() { return this;} }; // ----------- функция создания объекта ObjectImp* ObjectImp::create() { return new ObjectModelImp(); } // ================ пробуем int _tmain(int argc, _TCHAR* argv[]) { IObject* a = new ObjectModelImp(); IObject* b = a->create(); b->test(); ////// всё в порядке return 0; }
сабж - ошибка программиста, компилятор тут ни при чем
sildc
> сабж - ошибка программиста, компилятор тут ни при чем
+1 :)
Kloun
ObjectImp* a = new ObjectModelImp(); ObjectImp* b = a->create(); b->test(); // Теперь здесь всё валидно.
Отнаследуй ObjectModelImp от 3-х классов, чтоб реализация была у последних двух. Будут те же грабли, только ты уже сам не сможешь сказать какой из методов тебе нужен.
San
> У меня по умолчанию стоит 4-й уровень
bool keyPressed = (bool)GetAsyncKeyState( VK_SOMEKEY);
Suslik
> warning Cxxxx: i'm a blondie and couldnt convert dword to bool, possible loss
> of stuff
> как вообще предполагается относиться к таким ворнингам? это w3.
попробуйте так
bool keyPressed = !!GetAsyncKeyState(VK_SOMEKEY);
Тема в архиве.