Инициализация, временный объект, auto_ptr..
От: Lenikur Россия  
Дата: 23.09.04 08:07
Оценка:
Всем привет!

Ситуация:

typedef std::auto_ptr<CGRecordset> CGRecordsetPtr;
//...
class CAppDBFactory
{
// ...
public:
  CGRecordsetPtr CreatePreparedRecordset(const std::string&);
// ...
};
//...
CAppDBFactory Factory;
// Вот так все замечательно, компилятор не ругается
// CGRecordsetPtr pRecordset = Factory.CreatePreparedRecordset(sSQLText);
// а если делать так,
CGRecordsetPtr pRecordset;
pRecordset = Factory.CreatePreparedRecordset(sSQLText);
// то компилятор ругается
// Could not find a match for 'CGRecordsetPtr::operator =(CGRecordsetPtr)'

Действительно, такого определения в auto_ptr нет и быть не может, у = в качестве аргумента ссылка на CGRecordsetPtr.
Так вот я не пойму, почему при инициалицации копирующий конструктор срабатывает, а оператор = нет?
Re: Инициализация, временный объект, auto_ptr..
От: jazzer Россия Skype: enerjazzer
Дата: 23.09.04 08:22
Оценка:
Здравствуйте, Lenikur, Вы писали:

L>Так вот я не пойму, почему при инициалицации копирующий конструктор срабатывает, а оператор = нет?


ну так должно же что-то одно срабатывать: либо оператор=, либо конструктор копирования, потому что зачем выполнять одну и ту же работу дважды?

Ну а так как при инициализации мы должны инициализировать всякие базы, константы и ссылки (если они имеются), а такое позволено делать только конструктору копирования, то срабатывает он.

А оператору= остается уже работать только на сконструированных объектах.
Хотя общую часть инициализации, не затрагивающую константы, ссылки и базовые подобъекты, можно держать в operator=, а в конструкторе копирования звать его явно:
this->operator=(rhs);
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Инициализация, временный объект, auto_ptr..
От: Lenikur Россия  
Дата: 23.09.04 08:32
Оценка:
Здравствуйте, jazzer, Вы писали:

Спасибо за ответ

L>>Так вот я не пойму, почему при инициалицации копирующий конструктор срабатывает, а оператор = нет?

J>ну так должно же что-то одно срабатывать: либо оператор=, либо конструктор копирования, потому что зачем выполнять одну и ту же работу дважды?
Это понятно
Я наверное не правильно выразился, я не пойму почему инициализация компиляется, а присваивание нет.
Re: Инициализация, временный объект, auto_ptr..
От: Bell Россия  
Дата: 23.09.04 08:33
Оценка:
Здравствуйте, Lenikur, Вы писали:

L>Так вот я не пойму, почему при инициалицации копирующий конструктор срабатывает, а оператор = нет?


Какой компилятор?
Дело в том, что конструктор от "обычного" указателя в auto_ptr объявлен как explicit. Поэтому оба варианта не должны компилироваться.
Любите книгу — источник знаний (с) М.Горький
Re[2]: Инициализация, временный объект, auto_ptr..
От: Lenikur Россия  
Дата: 23.09.04 08:44
Оценка:
Здравствуйте, Bell, Вы писали:

B>Какой компилятор?

Это написано в C++ Builder 5.0
B>Дело в том, что конструктор от "обычного" указателя в auto_ptr объявлен как explicit. Поэтому оба варианта не должны компилироваться.

копирующий конструктор не объявлен как explicit.
Вот объявления:

auto_ptr(const auto_ptr<T>& rhs) throw();
auto_ptr<T>& operator=(const auto_ptr<T>& rhs) throw();

мне так кажется, что оба варианта должны компилироваться
Re[3]: Инициализация, временный объект, auto_ptr..
От: Bell Россия  
Дата: 23.09.04 08:48
Оценка:
Здравствуйте, Lenikur, Вы писали:

Так.
Что возвращает
Factory.CreatePreparedRecordset(sSQLText);

?
Любите книгу — источник знаний (с) М.Горький
Re[3]: Инициализация, временный объект, auto_ptr..
От: ssm Россия  
Дата: 23.09.04 08:50
Оценка:
Здравствуйте, Lenikur, Вы писали:


L>auto_ptr(const auto_ptr<T>& rhs) throw();

L>auto_ptr<T>& operator=(const auto_ptr<T>& rhs) throw();

L>мне так кажется, что оба варианта должны компилироваться

мне тоже и моему VC71 тоже
Re[4]: Инициализация, временный объект, auto_ptr..
От: Lenikur Россия  
Дата: 23.09.04 08:50
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, Lenikur, Вы писали:


B>Так.

B>Что возвращает
B>
B>Factory.CreatePreparedRecordset(sSQLText);
B>

B>?

CGRecordsetPtr CreatePreparedRecordset(const std::string&);
Re[5]: Инициализация, временный объект, auto_ptr..
От: Bell Россия  
Дата: 23.09.04 08:56
Оценка:
Здравствуйте, Lenikur, Вы писали:

L>
L>CGRecordsetPtr CreatePreparedRecordset(const std::string&);
L>


Сорри, не заметил в исходном посте.
В таком случае должны компилироваться оба варианта.
Любите книгу — источник знаний (с) М.Горький
Re[6]: Инициализация, временный объект, auto_ptr..
От: Lenikur Россия  
Дата: 23.09.04 09:11
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, Lenikur, Вы писали:


B>В таком случае должны компилироваться оба варианта.


Елки.. неужели опять долбанный Borland! или все-таки я?
Re[7]: Инициализация, временный объект, auto_ptr..
От: Bell Россия  
Дата: 23.09.04 09:18
Оценка:
Здравствуйте, Lenikur, Вы писали:

L>Елки.. неужели опять долбанный Borland! или все-таки я?

Скорее первое
Вот тебе пример, который компилится VC6 и Comeau:

#include <memory>

int main()
{
   std::auto_ptr<int> p1(0), p2(0);
   std::auto_ptr<int> p3 = p1;
   std::auto_ptr<int> p4;
   p4 = p2;
   return 0;
}


ЗЫ
Кстати приведенные тобой раньше сигнатуры конструктора копии и оператора присваивания не соответствуют стандарту — аргумент должен передаваться по неконстантной ссылке...
Любите книгу — источник знаний (с) М.Горький
Re[8]: Инициализация, временный объект, auto_ptr..
От: Lenikur Россия  
Дата: 23.09.04 11:33
Оценка:
Здравствуйте, Bell, Вы писали:

А попробуй компильнуть это:


B>
B>#include <memory>

class CFoo
{
public:
   char c;
   int i;
};

typedef std::auto_ptr<CFoo> CFooPtr;

CFooPtr f();

CFooPtr f()
{
   CFooPtr p(new CFoo);
   return p;
}

B>int main()
B>{
   CFooPtr p = f();
   CFooPtr p1;
   p1 = f();

B>   return 0;
B>}
B>


L>>Елки.. неужели опять долбанный Borland! или все-таки я?

B>Скорее первое
Боюсь что это я чего-то не вижу..

B>ЗЫ

B>Кстати приведенные тобой раньше сигнатуры конструктора копии и оператора присваивания не соответствуют стандарту — аргумент должен передаваться по неконстантной ссылке...

Кстати, посмотри в memory, там именно как я написал. Прикольная реализация
Re[9]: Инициализация, временный объект, auto_ptr..
От: Bell Россия  
Дата: 23.09.04 11:42
Оценка:
Здравствуйте, Lenikur, Вы писали:

L>А попробуй компильнуть это:

...
vc6, comeau — без проблем.

B>>ЗЫ

B>>Кстати приведенные тобой раньше сигнатуры конструктора копии и оператора присваивания не соответствуют стандарту — аргумент должен передаваться по неконстантной ссылке...

L>Кстати, посмотри в memory, там именно как я написал. Прикольная реализация

ну и что?
Любите книгу — источник знаний (с) М.Горький
Re[10]: Инициализация, временный объект, auto_ptr..
От: Lenikur Россия  
Дата: 23.09.04 12:02
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, Lenikur, Вы писали:


B>vc6, comeau — без проблем.


И правда без проблем, НЕНАВИЖУ BORLAND!! два дня копал!

L>>Кстати, посмотри в memory, там именно как я написал. Прикольная реализация

B>ну и что?
Вот что:
// TEMPLATE CLASS auto_ptr
template<class _Ty>
    class auto_ptr {
public:
    typedef _Ty element_type;
    explicit auto_ptr(_Ty *_P = 0) _THROW0()
        : _Owns(_P != 0), _Ptr(_P) {}
    auto_ptr(const auto_ptr<_Ty>& _Y) _THROW0()
        : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
    auto_ptr<_Ty>& operator=(const auto_ptr<_Ty>& _Y) _THROW0()
        {if (this != &_Y)
            {if (_Ptr != _Y.get())
                {if (_Owns)
                    delete _Ptr;
                _Owns = _Y._Owns; }
            else if (_Y._Owns)
                _Owns = true;
            _Ptr = _Y.release(); }
        return (*this); }
    ~auto_ptr()
        {if (_Owns)
            delete _Ptr; }
    _Ty& operator*() const _THROW0()
        {return (*get()); }
    _Ty *operator->() const _THROW0()
        {return (get()); }
    _Ty *get() const _THROW0()
        {return (_Ptr); }
    _Ty *release() const _THROW0()
        {((auto_ptr<_Ty> *)this)->_Owns = false;
        return (_Ptr); }
private:
    bool _Owns;
    _Ty *_Ptr;
    };
Re[11]: Инициализация, временный объект, auto_ptr..
От: MaximE Великобритания  
Дата: 23.09.04 12:25
Оценка:
Lenikur wrote:

> L>>Кстати, посмотри в memory, там именно как я написал. Прикольная реализация

> B>ну и что?
> Вот что:

Ничего прикольного — это убогая, не соответствующая стандарту реализация от MS VC++ 6. Несоответствуящая потому, что отсутствует ф-ция reset, убогая потому, что им пришлось добавить в класс флаг _Owns, который, будь auto_ptr<> реализован по стандарту, не был бы нужен.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9 gamma
Re[11]: Инициализация, временный объект, auto_ptr..
От: Bell Россия  
Дата: 23.09.04 12:40
Оценка:
Здравствуйте, Lenikur, Вы писали:

L>Вот что:

...
Что-то я не понял: это же реализация из VC6? Она, конечно не является образцом для подражания, но твой исходный пример с этой реализацией работает
Любите книгу — источник знаний (с) М.Горький
Re[12]: Инициализация, временный объект, auto_ptr..
От: Lenikur Россия  
Дата: 23.09.04 12:57
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, Lenikur, Вы писали:


L>>Вот что:

B>...
B>Что-то я не понял: это же реализация из VC6? Она, конечно не является образцом для подражания, но твой исходный пример с этой реализацией работает

Да все работает, просто я привел этот код, в ответ на твое замечание:

B>>Кстати приведенные тобой раньше сигнатуры конструктора копии и оператора присваивания не соответствуют стандарту — аргумент должен передаваться по неконстантной ссылке...


я и сам был удивлен увидев const.
Спасибо за помощь, Bell. Предлагаю закрыть эту тему. Кстати, попробовал на 6 C++ Builder, все работает.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.