Я ожидал, что при последнем присвоении будет использован непосредственно оператор присваивания из шаблона. На деле имеет место следующее: для правой части (IUnknown) компилятор сначала вызывает неявный конструктор от IUnk* (с целью, видимо, впоследствии использовать полученный объект в операторе копирования), в этом конструкторе имеет место такое же присвоение (справа IUnk*), так что снова вызывается неявный конструктор, и спустя малое время приходит stack overflow.
При этом попытка поставть breakpoint на оператор T& operator = (const IUnknown* a_pUnk) показывает, что он вообще не скомпилировался!
Если же сделать в CVideoEditWrapper'е конструктор от IUnk* типа "explicit", то при компиляции в нем вылезает ошибка "не определен оператор, принимающий в правой части const IUnk*", а оператор присваивания в шаблоне все равно не компилится.
Все эти танцы с бубном происходят в VC++ 6.0, с Микрософтским компилятором.
Шо делать?
Re: Не генерируется оператор присваивания в шаблоне класса
> Я ожидал, что при последнем присвоении будет использован непосредственно оператор присваивания из шаблона.
Этого не происходит, т.к. унаследованные операции присваивания, определенные в CDispinterfaceWrapper<>, скрываются операциями присваивания, неявно объявленными в классе CVideoEditWrapper.
В твоем коде есть и еще несколько неудачных моментов, среди которых использование операции присваивания *this = ... в конструкторе класса. При этом 1) переменные-члены остаются неинициализированными (в частности, похоже, отсутствует вызов InitCallVariables()); 2) operator = обычно пишется в расчете на то, что объект в левой части сконструирован, а в данном случае это не так.
> Шо делать?
Если придерживаться твоего дизайна, нужно "вручную" создать CVideoEditWrapper::operator =(CVideoEditWrapper const&) и делегирировать вызов базовому классу. С operator = (IUnknown const*) можно было бы поступить проще, написав "using CDispinterfaceWrapper<CVideoEditWrapper, _DVideoEdit>::operator =", но, т.к. VC++6, скорее всего, это переварить не в состоянии, тебе придется определить и его.
Не очень понятно, зачем, вообще, определяется класс CVideoEditWrapper вместо:
Павел Кузнецов,
ПК>Этого не происходит, т.к. унаследованные операции присваивания, определенные в CDispinterfaceWrapper<>, скрываются операциями присваивания, неявно объявленными в классе CVideoEditWrapper.
С одной стороны да. Торможу. Никак не привыкну, что шаблон — это не просто кусок, который бездумно подставляется в наследуемый класс, а полноценный предок.
А с другой — почему тогда при explicit'е он оператор присваивания по умолчанию сам не генерит, но и из предка брать не желает? Да и разве генерятся операторы? Мне казалось, что только конструкторы могут по умолчанию создаваться...
ПК>В твоем коде есть и еще несколько неудачных моментов, среди которых использование операции присваивания *this = ... в конструкторе класса.
Хм. Ну, наверное... В общем, по результатам раздумья, надо сделать в базовом классе функции для выполнения копирования от разных источников, а в наследниках вызывать эти функции по мере необходимости, в копирующих ли конструкторах, в операторах ли.
ПК>Если придерживаться твоего дизайна, нужно "вручную" создать CVideoEditWrapper::operator =(CVideoEditWrapper const&)
Ага, пришлось. И со вторым тоже.
ПК>и делегирировать вызов базовому классу.
да не, к чему он там.
ПК>Не очень понятно, зачем, вообще, определяется класс CVideoEditWrapper вместо:
Я тут упрощенно написал. В обоих классах есть еще функции, в базовом — общие для наследников, а в наследниках — те, которые в базовом приходится вызывать через приведение к наследнику.
Спасибо!
Re[3]: Не генерируется оператор присваивания в шаблоне класс
MicroCephalis,
> почему тогда при explicit'е он оператор присваивания по умолчанию сам не генерит, но и из предка брать не желает?
Копирующий оператор присваивания в этом случае все равно неявно объявляется, но использовать его компилятор в случае присваивания IUnknown* не может, т.к. для этого ему нужно неявно сконструировать CVideoEditWrapper из IUnknown*, что ты, поместив в объявлении соответствующего конструктора explicit, компилятору делать запретил. Убедиться в том, что копирующий оператор присваивания объявлен и доступен для использования можно попытавшись присвоить объекту CVideoEditWrapper другой объект этого же типа:
// где-то дальше
CVideoEditWrapper vew;
// еще дальше
vew = CVideoEditWrapper(); // Здесь.
> Да и разве генерятся операторы?
Да. Неявно объявляются (и в случае фактического использования определяются) следующие 4 специальные функции-члены: конструктор по умолчанию, конструктор копирования, копирующий оператор присваивания, деструктор. В этом легко убедиться, проанализировав следующий (валидный) пример:
struct S { };
int main()
{
S s; // конструктор по умолчанию
S s1(s); // конструктор копирования
s = s1; // копирующий оператор присваивания
// неявный вызов двух деструкторов
}
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[4]: Не генерируется оператор присваивания в шаблоне класс
Павел,
>> почему тогда при explicit'е он оператор присваивания по умолчанию сам не генерит, но и из предка брать не желает? ПК>Копирующий оператор присваивания в этом случае все равно неявно объявляется,
Вот-вот! Копирующий оператор. А нужен-то принимающий в правой части IUnknown*. И я его в шаблоне вроде бы предлагаю. Дык не берет, нос, можно сказать, воротит! Предпочитает заниматься неявным конструированием. Вот это поведение меня и удивляет.
>> Да и разве генерятся операторы? ПК>Да. Неявно объявляются 4 специальные функции-члены
ага, это я еще не забыл Мне показалось было из какой-то из предыдущих фраз, что генерируются любые операторы по мере необходимости, но это же чепуха, как сказала бы черная королева
Re[5]: Не генерируется оператор присваивания в шаблоне класс
MicroCephalis,
ПК>> Копирующий оператор присваивания в этом случае все равно неявно ПК>> объявляется,
M> Вот-вот! Копирующий оператор. А нужен-то принимающий в правой M> части IUnknown*. И я его в шаблоне вроде бы предлагаю. Дык не берет, M> нос, можно сказать, воротит! Предпочитает заниматься неявным M> конструированием. Вот это поведение меня и удивляет.
Функция в наследнике скрывает все одноименные функции в базовом классе.
Это же относится и к operator=. Соответственно, неявно объявленный
Derived::operator=(Derived const&)
скрывает как
Base::operator=(Derived const&)
так и
Base::operator=(IUnknown*)
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[6]: Не генерируется оператор присваивания в шаблоне класс
Павел Кузнецов,
ПК>Функция в наследнике скрывает все одноименные функции в базовом классе.
Опа. А вот это для меня ново. Я как-то был уверен, что скрываются только строго совпадающие ф-ии.
Спасибо большое!
Re[7]: Не генерируется оператор присваивания в шаблоне класс
Здравствуйте, Alxndr, Вы писали:
A>"Строго совпадающие" (в смысле, имеющие одинаковые сигнатуры) функции как раз-таки замещаются. Скрываются все остальные.
Это относится только к виртуальным функциям, если под "замещаются" ты подразумеваешь перевод "override". Невиртуальные функции, даже имеющие одинаковую сигнатуру, все равно скрываются (hide).
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[9]: Не генерируется оператор присваивания в шаблоне класс
Здравствуйте, Павел Кузнецов, Вы писали:
A>>"Строго совпадающие" (в смысле, имеющие одинаковые сигнатуры) функции как раз-таки замещаются. Скрываются все остальные.
ПК>Это относится только к виртуальным функциям, если под "замещаются" ты подразумеваешь перевод "override". Невиртуальные функции, даже имеющие одинаковую сигнатуру, все равно скрываются (hide).
Да, естественно, я имел в виду именно виртуальные функции