Здравствуйте, Germes, Вы писали:
G>почему применение 2 декоратора отменяет действие первого ?
Потому, что ты не понимаешь, как в С++ работают виртуальные функции.
То, какая функция позовётся, определяется исключительно наиболее выведенным типом, а не полями объекта. Так что у типов A, foo1_decorator<A>, foo2_decorator<A> определены методы так, как они определены, вне связи с тем, каой там был аргумент конструктора!
Для того, чтобы применить оба, тебе надо было не аргументы в конструктор передавать, а юзать тип foo1_decorator<foo2_decorator<A> >
С другой стороны, если тебе хочется динамического связывания, то можно было прямо вот в A завести ПЕРЕМЕННЫЕ, в которых так или иначе хранить информацию о том, какой именно метод какого именно класса надо позвать.
Ну и вообще, обычно когда хочется смешать шаблоны и виртуальные методы, это обычно говорит, об ошибке дизайна.
Но это путь нереального геморра с владением объектами!
У тебя, кстати, в оригинальном примере течёт память!
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Vamp, Вы писали:
V>А что тебя, собственно, удивляет? V>p_A = new foo2_decorator<A>(*p_A);
V>Теперь у тебя p_A указывает на объект типа foo2_decorator, в нем foo1 не переопределен. Как еще могло бы быть?
А разве таблица виртуальных методов не копируется ? Скорее происходит усечение.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Germes, Вы писали:
E>То, какая функция позовётся, определяется исключительно наиболее выведенным типом, а не полями объекта. Так что у типов A, foo1_decorator<A>, foo2_decorator<A> определены методы так, как они определены, вне связи с тем, каой там был аргумент конструктора!
Скорее виртуальная таблица не изменяется при копировании.
Кстати я не спрашивал, как это можно сделать(достаточно было завести базовый декоратор).
class I_A_decorator : public A
{
I_A* owner_;
public:
I_A_decorator(I_A* p_owner):
owner_(p_owner)
{
}
virtual void foo1()
{
owner_->foo1();
}
virtual void foo2()
{
owner_->foo2();
}
};
E>У тебя, кстати, в оригинальном примере течёт память!
Я в курсе .
G>А разве таблица виртуальных методов не копируется ? Скорее происходит усечение.
А как бы она могла копироваться?
А *вдруг* той реализации, на которую скопируется указатель, будут нужны какие-то поля в объекте?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Germes, Вы писали:
G>Скорее виртуальная таблица не изменяется при копировании.
Не очень понимаю, что значит "не изменяется", если речь идёт о создании объекта.
Но такое поведение, которого хотел ты, невозможно.
E>>У тебя, кстати, в оригинальном примере течёт память! G>Я в курсе .
Ну и зачем тогда? Можно же автоматические переменные сдалть было!
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Germes, Вы писали:
G>>Скорее виртуальная таблица не изменяется при копировании. E>Не очень понимаю, что значит "не изменяется", если речь идёт о создании объекта.
скорее всего ожидалось что при создании объекта можно динамически изменить виртуальную таблицу путем подмены инстанса базового класа.
E>Но такое поведение, которого хотел ты, невозможно.
это поведение хотели получить люди писавший код ,сильно упрощенный вариант которого я и привел.
Четкого ответа почему это не работает, я дать не смог вот по этому и запостил на форум.
E>>>У тебя, кстати, в оригинальном примере течёт память! G>>Я в курсе . E>Ну и зачем тогда? Можно же автоматические переменные сдалть было!
какие автоматические переменные ???? это пример демонстрирующий конкретную проблему. Не более того.
Erop,
большая просьба к вам ,
не стоит уводить дискуссию в сторону всякими ненужными предложениями , как это можно реализовать ,поиском утечек и т. д.
Я все это знаю и без вас.
Здравствуйте, Germes, Вы писали:
E>>Но такое поведение, которого хотел ты, невозможно. G>это поведение хотели получить люди писавший код ,сильно упрощенный вариант которого я и привел. G>Четкого ответа почему это не работает, я дать не смог вот по этому и запостил на форум.
Либо они совсем не подумали, либо ты их недопонял. Если они не совсем лохи, то вероятнее второе. Иногда причудливую творческую мысль С++-программиста довольно трудно понять, однако.
Почему нельзя копировать таблицы виртуальных функций? Вот пример:
struct A {
virtual ~A() {}
virtual int foo() = 0;
};
struct B : A {
int Field;
int foo() { return Field++; }
};
struct Decorator : A {
Decorator( A* a ) : A( *a ) {}
};
int bar()
{
B b;
Decorator d( &b );
return d.foo(); // Если бы было так, как ты думаешь хотели те люди,
// то какому полю какого класса должно было быть сделано ++?
}
G>Erop, G>большая просьба к вам , G>не стоит уводить дискуссию в сторону всякими ненужными предложениями , как это можно реализовать ,поиском утечек и т. д. G>Я все это знаю и без вас.
Ну так и пиши примеры, в которых есть только ОДНА проблема. ИМЕННО та, про которую ты хочешьл спросить.
А то уровень человека, которому нужна помощь не ясен из вопроса, а среди кучи ошибок трудно понять, что именно не устраивает...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Germes, Вы писали:
G>Здравствуйте, Erop, Вы писали:
E>>Здравствуйте, Germes, Вы писали:
G>>>Скорее виртуальная таблица не изменяется при копировании. E>>Не очень понимаю, что значит "не изменяется", если речь идёт о создании объекта.
G>скорее всего ожидалось что при создании объекта можно динамически изменить виртуальную таблицу путем подмены инстанса базового класа.
"Виртуальная таблица" в С++ — это сущность уровня класса, а не уровня объекта (в Стандарте это формулируется несколько иначе, но тебе это не нужно, а смысл тот же).
Т.е. она одна на все объекты данного класса (и чаще всего реализуется в виде указателя на эту таблицу, которая одна на всех. Так что даже если ты пролезешь в нее при помощи грязных хаков и что-нть там поменяешь — ты поменяешь поведение всех объектов этого класса).
Если ты хочешь иметь виртуальную таблицу на уровне объекта — тебе придется реализовать ее руками (не ахти как сложно, в принципе).
Здравствуйте, andrey_nado, Вы писали:
_>Почему?
Ну по многим причинам. Кроме того, смешать можно по разному
_>Неужели никогда не приходилось создавать иерархию классов, параметризованных каким-нибудь типом?
Ну, в целом старался избегать. Ясно, что у какой-то системы типов может быть два независимых аспекта. И один может быть сделан через виртуальные методы, а другой через шаблоны. Но под "смешать" я имел в виду немного другое.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском