Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Red Line, Вы писали:
К>RL>>// Операции с указателем
RL>>>>T& operator*() { assert(m_pI != NULL); return *m_pI; }
К>
RL>>Я ни как не вразумею, — как нужно читать синтаксис этого оператора.
К>Проще некуда:
К>К>struct Data
К>{
К> int x;
К> void foo();
К>};
К>// некоторые функции...
К>void accept_data(Data d); // входной параметр
К>void fill_data(Data& d); // выходной параметр
К>struct SmartPtr
К>{
К> Data* p;
К> Data& operator* () { return *p; }
К>};
К>main()
К>{
К> Data* p1;
К> SmartPtr p2;
К> . . . . .
К> // обычный указатель // явный доступ к члену умного // то же самое,
К> // -- обычному указателю // но завёрнутое в оператор разыменования
К> fill_data(*p1); fill_data(*(p2.p)); fill_data(*p2);
К> accept_data(*p1); accept_data(*(p2.p)); accept_data(*p2);
К>}
К>
К>Видишь, что внешне работа с обычным указателем (левый столбец) выглядит так же, как с умным (правый).
К>Перекрытый оператор служит именно этой цели: одинаковости внешнего вида.
RL>>Мне понятна запись:
RL>>RL>>С operator + (const C lPar, const C rPar);
RL>>
RL>>Читаю (в соответствии с тем как Вы меня учили)
RL>>Внешний оператор;
RL>>двухместный инфиксный оператор (операнд слева — lPar, операнд справа — rPar);
RL>>Возможны две формы вызова
RL>>явная:
К>RL>>C x,y,z;
RL>>z = +(x,y);
К>
RL>>и операторная:
К>RL>>С x,y,z;
RL>>z = x+y;
К>
RL>>Верно?
К>Неверно!!!
К>Операторная запись:
К> z = x+y;
К>Функциональная запись (если оператор внешний):
К> z = operator+ (x,y);
К>Функциональная запись (если оператор — функция-член):
К> z = x.operator+ (y);
RL>>Теперь оператор-член класса:
RL>>RL>> class С
RL>>{
RL>> C add(val1, val2);
RL>> C operator + (C rPar) const {return add(*this, rPar);}
RL>>};
RL>>
RL>>Оператор-член класса; (подразумевается, что если левый аргумент не указан то это всегда *this)
К>Он не "если не указан", а всегда не указан. У любого метода объекта есть неявный параметр — указатель на сам объект.
RL>>двухместный (бинарный) и вроде бы инфиксный;
RL>>Явная форма вызова:
К>RL>>С obj;
RL>>C anyPar;
RL>>C res;
RL>>res = obj.operator + (anyPar);
К>
//равносильно obj+anyPar? Т.е текущий объект складывается с параметром, и что будет
блин не догоняю
((
RL>>Операторная форма:
К>RL>>С obj;
RL>>C anyPar;
RL>>C res;
RL>>res = +anyPar;
К>
К>// правый операднд (параметр) указан явно, а левый есть объект. Какой??? anyPar-объект, а тот что в операторе где????
К>Ещё раз. Операторная форма записи НИЧЕМ не отличается от операций над арифметическими типами.
К>Ключевое слово "operator" — это НЕ ОПЕРАТОРНАЯ ФОРМА ЗАПИСИ. А функциональная.
RL>>Мне бы хотелось в такой же форме разобрать и эти операторы:
RL>>RL>> class cPtr
RL>>{
RL>> private:
RL>> T* p;//указатель на искомый интерфейс
RL>> public:
RL>> operator T*() { return m_pI; }
RL>> T& operator*() { return *m_pI; }
RL>> T** operator&() { return &m_pI; }
RL>> T* operator->() { return m_pI; }
RL>>};
RL>>
RL>>Прошу извинить если надоедаю
К>Ну и что здесь непонятного? Попробуй поработать за компилятора.
К>К>void foo(T* pointer);
К>void bar(T value);
К>void xyz(T& reference);
К>void get(T** address_of_pointer);
К>main()
К>{
К> cPtr ptr;
К> get(&ptr); get(&(ptr.m_pI));
К> foo(ptr); foo(ptr.m_pI);
К> bar(*ptr); bar(*(ptr.m_pI));
К> xyz(*ptr); xyz(*(ptr.m_pI));
ptr->>call(); ptr.m_pI->call();
К>}
К>
// обычный указатель // явный доступ к члену умного // то же самое,
К> // -- обычному указателю // но завёрнутое в оператор разыменования
К> fill_data(*p1); fill_data(*(p2.p)); fill_data(*p2);
К> accept_data(*p1); accept_data(*(p2.p)); accept_data(*p2);
Кажется я понял !!!
fill_data(*p2);
accept_data(*p2);
*p2 — это и есть вызов операторной функции, т.е не звёздочка сама по себе, а именно "*p2" и есть вызов
аналогичный p2.operator*() для экземпляра p2... Этот вызов приведёт к тому, что отработает код:
return *p;
и функция accept_data получит аргумент верного тип (типа Data).
Ну так или нет?