И еще один вопросец :)
От: LaptevVV Россия  
Дата: 04.06.08 08:15
Оценка:
Есть класс:
//----------- файл TArray.h
#include <iostream>
class Array 
{ public:
            // типы исключений:
    class bad_Index {};         // индекс вне диапазона
    class bad_Range {};         // если левый адрес > правый адрес
    class bad_Size {};          // неправильный размер
            // типы:
    typedef double         value_type;            
    typedef double*        iterator;
    typedef const double*  iterator_const;
    typedef double&        reference;             
    typedef const double&  const_reference;       
    typedef std::size_t    size_type;             
            // конструкторы/присваивание/деструктор:
    Array( size_type size, value_type k = 0.0 );
    Array( const Array& array );
    Array( iterator_const, iterator_const );
    ~Array(){ delete[] elems;   elems = 0; }           // освобождаем память
    Array& operator=( const Array& );
    size_type size() const { return Size; }        // текущий размер массива
            // доступ к элементам:
    reference       operator[]( size_type );
    const_reference operator[]( size_type ) const;
    reference       front() { return elems[0]; }           // первый элемент
    const_reference front() const { return elems[0]; }
    reference back() { return elems[size() - 1]; }      // последний элемент
    const_reference back() const { return elems[size() - 1]; }  
    void Swap( Array &other )                 // обменять с другим массивом
    { std::swap( elems, other.elems );           // стандартная функция обмена
      std::swap( Size, other.Size );
    }
    friend std::ostream& operator<< (std::ostream &t, const Array &V );
private:
    size_type Size;                           // выделено элементов в памяти
    value_type * elems;                               // указатель на данные
    void rangecheck ( size_type i ) const 
    {   if ( i >= size() )  throw bad_Index(); }
};
// ----------------файл TArray.cpp
#include "TArray.h"
#include <iostream>
Array::Array( size_type size, value_type k )
{   if ( size == 0 ) throw bad_Size();               // генерация исключения
    Size = size;
    elems = new value_type[Size];                   // создали массив
    for( size_type i = 0; i < Size; ++i )         // заполняем массив
        elems[i] = k;                               // значение по умолчанию
} 
Array::Array( iterator_const begin, iterator_const end ) 
{   if ( begin >= end ) throw bad_Range();           // генерация исключения
    Size = end - begin;                              // количество элементов
    elems = new value_type[Size];                   // создаем массив
    size_type i = 0;
    while( begin != end )                                // заполняем массив
        elems[i++] = *begin++;                        // копируем из массива
}
Array::Array( const Array &t )
: Size( t.Size ), elems( new value_type[Size] )
{    for( size_type i = 0; i < Size; ++i ) elems[i] = t.elems[i]; }
 
Array& Array::operator=( const Array &t )
{   Array temp( t );                 // временнный локальный объект temp = t
    Swap( temp );                         // обмен полями с текущим объектом
    return *this;                         // возврат нового текущего объекта
}                                                   // объект temp уничтожен
   
Array::reference Array::operator[]( size_type index )
{   if ( index < size() ) return elems[index];
    else throw bad_Index();                          // генерация исключения
}
Array::const_reference Array::operator[]( size_type index ) const
{   rangecheck( index );          // проверка индекса и генерация исключения
    return elems[index]; 
}
std::ostream& operator<< ( std::ostream &t, Array const& V )
{ if( V.size() > 0 )
     for( std::size_t i = 0; i < V.size(); ++i) t << V.elems[i] << ' ';
  return t;
}

В реализациях типы, объявленные в typedef, пишутся без префиксов. А если тип — возвращаемый, то требуется задавать префикс класса. Как внятно сформулировать такое требование? Или это только в Visual C++. NET 2005?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
префикс
Re: И еще один вопросец :)
От: jazzer Россия Skype: enerjazzer
Дата: 04.06.08 08:21
Оценка: +1
Здравствуйте, LaptevVV, Вы писали:

LVV>В реализациях типы, объявленные в typedef, пишутся без префиксов. А если тип — возвращаемый, то требуется задавать префикс класса. Как внятно сформулировать такое требование? Или это только в Visual C++. NET 2005?


Ну ты даешь Срочно в отпуск!!!

Твои typedef-ы в какой области видимости объявлены?
Правильно, в классе.
Значит, где их можно поминать без квалификации?
Правильно, только в той же или вложенной области видимости (т.е. только внутри класса и его членов/наследников).
А функция в какой области видимости объявлена?
Правильно, на уровне пространства имен, т.е. в области, внешней по отношению к твоему классу.
Так чему ж ты удивляешься?
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]: И еще один вопросец :)
От: LaptevVV Россия  
Дата: 04.06.08 08:33
Оценка:
Здравствуйте, jazzer, Вы писали:

LVV>>В реализациях типы, объявленные в typedef, пишутся без префиксов. А если тип — возвращаемый, то требуется задавать префикс класса. Как внятно сформулировать такое требование? Или это только в Visual C++. NET 2005?

J>Ну ты даешь Срочно в отпуск!!!
Не... К сожалению, мне еще полтора месяца на реботе телепаться...
J>Твои typedef-ы в какой области видимости объявлены?
J>Правильно, в классе.
J>Значит, где их можно поминать без квалификации?
J>Правильно, только в той же или вложенной области видимости (т.е. только внутри класса и его членов/наследников).
J>А функция в какой области видимости объявлена?
J>Правильно, на уровне пространства имен, т.е. в области, внешней по отношению к твоему классу.
То есть возвращаемый тип из метода класса относится к внешней области видимости. Тут можно провести аналогию с перегрузкой: возвращаемый тип не учитывается при перегрузке. Так легче запомнят.
J>Так чему ж ты удивляешься?
Не удивляюсь, а просто принимаю как есть, не особо задумываясь о причинах.
Надо префикс писать — значит пишем, можно не писать — не пишем...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[3]: И еще один вопросец :)
От: jazzer Россия Skype: enerjazzer
Дата: 04.06.08 08:43
Оценка:
Здравствуйте, LaptevVV, Вы писали:

J>>А функция в какой области видимости объявлена?

J>>Правильно, на уровне пространства имен, т.е. в области, внешней по отношению к твоему классу.
LVV>То есть возвращаемый тип из метода класса относится к внешней области видимости. Тут можно провести аналогию с перегрузкой: возвращаемый тип не учитывается при перегрузке. Так легче запомнят.

Возвращаемого типа, как ты о нем говоришь, не существует в природе.
Существует сигнатура функции, которую ты объявляешь, и всё (и возвращаемый тип, и типы аргументов) в ней находится в той области видимости, где ты ее объявляешь, в твоем случае — в области, внешней по отношению к классу, которая внутренних имен класса не увидит, пока ты не ткнешь ее туда носом (при помощи квалификации).
Ты с тем же успехом можешь попытаться объявить переменную внутреннего типа класса — тут у тебя не возникает вопросов, почему надо явно квалифицировать:
Array::value_type dummy;



J>>Так чему ж ты удивляешься?

LVV>Не удивляюсь, а просто принимаю как есть, не особо задумываясь о причинах.
LVV>Надо префикс писать — значит пишем, можно не писать — не пишем...

Стыдись! А потом удивляешься, почему студенты тупо зубрят и ничего не понимают при этом.
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[4]: И еще один вопросец :)
От: LaptevVV Россия  
Дата: 04.06.08 13:51
Оценка: 1 (1)
Здравствуйте, jazzer, Вы писали:

J>>>А функция в какой области видимости объявлена?

J>>>Правильно, на уровне пространства имен, т.е. в области, внешней по отношению к твоему классу.
LVV>>То есть возвращаемый тип из метода класса относится к внешней области видимости. Тут можно провести аналогию с перегрузкой: возвращаемый тип не учитывается при перегрузке. Так легче запомнят.
J>Возвращаемого типа, как ты о нем говоришь, не существует в природе.
J>Существует сигнатура функции, которую ты объявляешь, и всё (и возвращаемый тип, и типы аргументов) в ней находится в той области видимости, где ты ее объявляешь, в твоем случае — в области, внешней по отношению к классу, которая внутренних имен класса не увидит, пока ты не ткнешь ее туда носом (при помощи квалификации).
Фигасе! Все имена, объявленные в typedef, прекрасно распознаются без всяких префиксов. И в списке параметров, и внутри тела метода. Кроме тех, которые объявлены на месте возвращаемого типа. Вот я и спрашиваю — мож особенность Mикрософта?
J>Ты с тем же успехом можешь попытаться объявить переменную внутреннего типа класса — тут у тебя не возникает вопросов, почему надо явно квалифицировать:
J>
J>Array::value_type dummy;
J>

Это совсем другое дело! Вне тела определяемого метода — так и делается, и тут вопросов не возникает. Внутри тела — прекрасно и без префикса работает.
J>>>Так чему ж ты удивляешься?
LVV>>Не удивляюсь, а просто принимаю как есть, не особо задумываясь о причинах.
LVV>>Надо префикс писать — значит пишем, можно не писать — не пишем...
J>Стыдись! А потом удивляешься, почему студенты тупо зубрят и ничего не понимают при этом.
Не, в нашем деле тупо не позубришь. Я требую, чтоб прога работала. Причем, на машине заказчика, то есть в учебном классе. Если ему для этого требуется с префиксом класса познакомиться — так пусть в MSDN слазит и почитает.
А я вот любопытный, меня и интересует, почему то с префиксом, то без префикса.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[5]: И еще один вопросец :)
От: jazzer Россия Skype: enerjazzer
Дата: 04.06.08 15:40
Оценка: 1 (1)
Здравствуйте, LaptevVV, Вы писали:

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


J>>>>А функция в какой области видимости объявлена?

J>>>>Правильно, на уровне пространства имен, т.е. в области, внешней по отношению к твоему классу.
LVV>>>То есть возвращаемый тип из метода класса относится к внешней области видимости. Тут можно провести аналогию с перегрузкой: возвращаемый тип не учитывается при перегрузке. Так легче запомнят.
J>>Возвращаемого типа, как ты о нем говоришь, не существует в природе.
J>>Существует сигнатура функции, которую ты объявляешь, и всё (и возвращаемый тип, и типы аргументов) в ней находится в той области видимости, где ты ее объявляешь, в твоем случае — в области, внешней по отношению к классу, которая внутренних имен класса не увидит, пока ты не ткнешь ее туда носом (при помощи квалификации).
LVV>Фигасе! Все имена, объявленные в typedef, прекрасно распознаются без всяких префиксов. И в списке параметров, и внутри тела метода. Кроме тех, которые объявлены на месте возвращаемого типа. Вот я и спрашиваю — мож особенность Mикрософта?

Спасибо, что возразил — полез в Стандарт, конкретно, в 3.3.6/1, последняя строчка длинного абзаца пятого пункта прямо над примером, после последней запятой (чувствую себя юристом)
В общем, область видимости класса в случае функции-члена класса начинается сразу после имени функции:
A::X A::f(....)
         ^ вот здесь начинается class scope

так что список параметров действительно находится уже внутри области видимости класса.
В принципе, я не вижу особых причин, кроме удобства, делать именно так.

А почему возвращаемое значение должно быть квалифицировано?
Потому что так положено по грамматике: вначале тип, потом идентификатор, потом все остальное (в случае функции — список аругментов в скобках).
И когда мы парсим тип возвращаемоого значения, мы еще не знаем, что там будет дальше — объявление переменной, или определение члена-функции, или еще что-нть. Поэтому мы сначала парсим то, что вначале, смотрим, что это тип, после чего врубаем грамматику для объявлений.
В принципе, конечно, можно было бы потребовать, чтоб компилятор был умным и просто пропускал то, что вначале, пока не распарсит то, что дальше и не поймет, что это определение функции, и уже после этого попытался искать тип в области видимости класса. Навскидку я не вижу, почему это могло бы не работать.
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[6]: И еще один вопросец :)
От: LaptevVV Россия  
Дата: 05.06.08 06:35
Оценка:
Здравствуйте, jazzer, Вы писали:

LVV>>Фигасе! Все имена, объявленные в typedef, прекрасно распознаются без всяких префиксов. И в списке параметров, и внутри тела метода. Кроме тех, которые объявлены на месте возвращаемого типа. Вот я и спрашиваю — мож особенность Mикрософта?


J>Спасибо, что возразил — полез в Стандарт, конкретно, в 3.3.6/1, последняя строчка длинного абзаца пятого пункта прямо над примером, после последней запятой (чувствую себя юристом)

J>В общем, область видимости класса в случае функции-члена класса начинается сразу после имени функции:
J>
J>A::X A::f(....)
J>         ^ вот здесь начинается class scope
J>

J>так что список параметров действительно находится уже внутри области видимости класса.
J>В принципе, я не вижу особых причин, кроме удобства, делать именно так.
Спасибо за ссылку в стандарт, а то я лазил-лазил, и как -то пропустил.
J>А почему возвращаемое значение должно быть квалифицировано?
J>Потому что так положено по грамматике: вначале тип, потом идентификатор, потом все остальное (в случае функции — список аругментов в скобках).
J>И когда мы парсим тип возвращаемоого значения, мы еще не знаем, что там будет дальше — объявление переменной, или определение члена-функции, или еще что-нть. Поэтому мы сначала парсим то, что вначале, смотрим, что это тип, после чего врубаем грамматику для объявлений.
J>В принципе, конечно, можно было бы потребовать, чтоб компилятор был умным и просто пропускал то, что вначале, пока не распарсит то, что дальше и не поймет, что это определение функции, и уже после этого попытался искать тип в области видимости класса. Навскидку я не вижу, почему это могло бы не работать.
Да, с точки зрения реализации синтаксического разбора — все логично. Спасибо!
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.