Страница 2 из 3

Добавлено: 09 дек 2004, 13:05
Romeo
В том то и дело, что только в случае ссылки время жизни объекта увеличивается до пределов текущего блока. Во всех остальных случаях возвращаемый объект живёт только до завершения операции присваивания.

Добавлено: 09 дек 2004, 13:21
Eugie
Да, ты прав. Но в случае _bstr_t твой пример выдаст ошибку даже если бы объект-результат жил до конца блока

Добавлено: 09 дек 2004, 13:27
HKarel
Хотел ответить на предпоследнее сообщение Eugie, но последние два сообщения и так все сказали :)
Тогда подъитожим: код Romeo должен заработать если его переписать следующим образом

Код: Выделить всё

_bstr_t GetSomeBSTRString(); 
... 
void SomeFunction() 
{ 
   ... 
   //char * strMyConvertedString = GetSomeBSTRString(); 
   //cout << strMyConvertedString; // access violation exception 
   _bstr_t &strMyConvertedString = GetSomeBSTRString(); 
   cout << strMyConvertedString.operator char*();
   ... 
}

Добавлено: 09 дек 2004, 13:31
Absurd
А почему cout<<GetSomeBSTRString(); не написать?

Добавлено: 09 дек 2004, 13:41
Eugie
Дык, не умеет ostream с _bstr_t работать и vice versa

Добавлено: 09 дек 2004, 14:01
Absurd
Дык, не умеет ostream с _bstr_t работать и vice versa
У него же (у _bstr_t) есть оператор для неявного преобразования к char* ?

Добавлено: 09 дек 2004, 15:26
Eugie
А компилятор глупый, об этом не знает :) Без явного приведения никак (см. последнее сообщение HKarel)

Добавлено: 09 дек 2004, 15:51
Absurd
_bstr_t str = L"Hello world\n";
std::cout<<str; // не компилируется
std::cout<<(char *)str; // компилируется

Хм, странно... Я помнится года 4 назад, когда был еще студентом, писал класс для работы с однобитными битмапами.
Дык я перегружал operator=(const bool val) и operator bool() cost в прокси - классе так, что конструкции вида

Код: Выделить всё

bw_bitmap(100,100) = true;
if (bw_bitmap(100,100)) {
 ...
}
Компилировались и работали.

Добавлено: 09 дек 2004, 16:04
Romeo
Да, ты прав. Но в случае _bstr_t твой пример выдаст ошибку даже если бы объект-результат жил до конца блока.
Не выдаст. См. код _bstr_t. Выделенная под конвертацию строка удаляется лишь в деструкторе внутреннего класса, когда количество ссылок на контейнер BSTR строки не станет нулевым.
А компилятор глупый, об этом не знает. Без явного приведения никак (см. последнее сообщение HKarel)
Нет, компилятор не глупый. Он просто не знает какой оператор вызвать для того, чтобы вывести эту сроку. cout умеет выводить как обычные строки, так и BSTR строки, точно также, как и _bstr_t может интерпритироваться двояко, благодаря перегруженным в ней операторам приведения. Речь идёт не о глупости компилятора, а о том, что ситуация "ambigous" - неоднозначная. Если бы не это одно НО, то явного преобразования писать бы не пришлось. Естественно в данном надуманном случае лучше вообще использовать

Код: Выделить всё

cout << (BSTR)GetSomeBSTRString();
по той причине, что мы не будем тратить время на конвертацию.

И вообще, хватит обсуждать пример, который я написал с потолка :) . Ситуация, которая у меня возникла с год назад, конечно же была не идентичная. Я просто сделал набросок, чтобы показать общий принцип ошибки. Замечания типа "а почему бы нам не сделать так" - неуместны.

Добавлено: 09 дек 2004, 16:04
Eugie
2 Absurd
Не знаю, почему так. Могу только предположить, что в твоем случае ситуация с т.з. компилятора более определенная. Для ostream, наверное, накладно делать предположения о возможных неявных преобразованиях - потенциально их может быть слишком много.