Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Константы в шаблонах. Помогите разобраться, когда писать const T& а когда просто T& 
:(
    Опции темы
v_enom
Дата 4.6.2009, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 11.10.2006

Репутация: нет
Всего: нет



Ребята, помогите понять константы (листинг 19.2 книги С++ за21  день д.Либерти)

вот есть перегруженный оператор T& operator[], которые возвращает ссылку, почему-то для используется другая реализация перегруженного оператора Array<T>::Array(const Array &rhs)  с константой  const T& operator[]. Почему так - не понятно.

в main эта функция Array<T>::Array(const Array &rhs)  вызывается при присваивании.

Код

int _tmain(int argc, _TCHAR* argv[])
{
    Array<int> theArray;    
    Array<Animal>  theZoo;

Animal *pAnimal = NULL;
    for(int i=0;i<theArray.GetSize();i++)
    {
        theArray[i] = i*2;
        pAnimal = new Animal(i*3);
        theZoo[i] = *pAnimal;
        delete pAnimal;

    }    
    Array<Animal> newZoo;

    newZoo = theZoo;         // вот тут!!!!
    return 0;
}



остальной код

Код

class Animal
{
public:
    Animal();
    Animal(int weight);
    ~Animal(){};
    int GetWeight() const {return itsWeight;}
    void Display() const {std::cout << itsWeight;}
    void SetWeight(int a) 
    {    itsWeight = a;    }
    void SetWeight(int a) const    
    {
        cout<<itsWeight;
    }

     Animal& operator+(int a)
    {
        itsWeight=itsWeight+a;
        return *this;
    }


private:
    int itsWeight;
    char* itsName;
};

Animal::Animal(int weight):itsWeight(weight)
{
    itsName = "AnimalName";
}

Animal::Animal():itsWeight(0)
{
    itsName = "AnimalName";
}




const int DefaultSize = 10;
template <class T>
class Array    
{
    public:
        
        Array(int itsSize = DefaultSize);
        Array(const Array& rhs);
        ~Array(){delete [] pType;}

        Array& operator = (const Array&);
        
        T& operator[] (int offSet) 
            {
                return pType[offSet];
        }

        const T& operator[](int offSet) const                     // вызываемая функция
            {
                return pType[offSet];
        }
        int GetSize()const {return itsSize; }
        friend void Intrude(Array<int> theArray);
    private:
        T* pType;
        int itsSize;        
}; 



template <class T>
Array<T>::Array(const Array &rhs)
{
    itsSize = rhs.GetSize();
    pType = new T[itsSize];
    for(int i = 0;i<itsSize; i++)
    {
        pType[i]= rhs[i];                         // вот тут вызвается функция  const T& operator[]  почему именно она? а не  T& operator[]
    }
}

PM MAIL   Вверх
jonie
Дата 4.6.2009, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



ну так rhs у тебя константная ссылка, вот и вызывается наиболее "близкий" по типу аргумента operator[].


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
v_enom
Дата 4.6.2009, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 11.10.2006

Репутация: нет
Всего: нет



Цитата(jonie @  4.6.2009,  17:56 Найти цитируемый пост)
ну так rhs у тебя константная ссылка, вот и вызывается наиболее "близкий" по типу аргумента operator[]. 


не понял. Обяъсни связь между тем, что rhs у меня константа и тем, что я возвращаю ссылку на константу. К тому же мне не понятно, почему сама rhs - константа. По идее я же могу менять значния содержимого в rhs, если я напишу еще функцию и она будет это делать!
PM MAIL   Вверх
jonie
Дата 4.6.2009, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



Цитата
По идее я же могу менять значния содержимого в rhs, если я напишу еще функцию и она будет это делать!

да, тогда вызовется operator[] "без константности".



--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
v_enom
Дата 4.6.2009, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 11.10.2006

Репутация: нет
Всего: нет



 smile 
ни чего не понял, пожалуйста объясните понятно с примерами.
Я же разбираю новый материал...

1. почему rhs обязательно как константная ссылка должна быть?
ведь я не создаю 
Array<Animal>  const newZoo; 
или что-то типо того. от куда тогда необходимость в  констанотности появляется? при передаче? так какой в ней смысл тогда, если я все равно newZoo не делаю константой....

2. почему возвращаться должна обязательно const T& ? ведь есть просто T& для operator[] ????

почему так отличается объявление в классе от реализации:

Код

class
{...
Array& operator = (const Array&);
...
}

template <class T>
Array<T>& Array<T>::operator=(const Array &rhs)

а???





Это сообщение отредактировал(а) v_enom - 4.6.2009, 19:23
PM MAIL   Вверх
jonie
Дата 4.6.2009, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



вам стоит почитать про перегрузку вообще и про константность в целом.
начинте с этого: http://habrahabr.ru/blogs/cpp/59558/
ну и книжки и гугл подскажут.

напишите простые классы с пустыми функциями и выводом в них вроде std::cout<<"cont foo() called\n"; и проанализируйте как будет компилятор выделять что вызывать. И вообще на это есть стандарт.

Цитата

почему так отличается объявление в классе от реализации:
Код

class
{...
Array& operator = (const Array&);
...
}

template <class T>
Array<T>& Array<T>::operator=(const Array &rhs)


а???
потому что template <class T>, обявленные для класса "применяется" к каждому его члену корый декларирован, а в определении приходится указывать явно специализацию шаблона T типом.
тут про специализацию: http://habrahabr.ru/blogs/cpp/54762/


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
mes
Дата 4.6.2009, 23:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(v_enom @  4.6.2009,  18:09 Найти цитируемый пост)
ни чего не понял, пожалуйста объясните понятно с примерами.

Вот Вам простой пример, поняв который разберетесь и со своей задачей.
Код

struct T
{
    void f ()       { std::cout << "without const"<< std::endl; }
    void f () const { std::cout << "with const"<< std::endl; }
};

int main()
{

T o;

T const& crf = o;
T & rf = o;

 crf.f ();
 rf.f();
}

Подсказка : если this указатель на константу,  то следовательно вызовется константная версия. Т.е const написанная после функции является модификатором скрытого параметра this.






--------------------
PM MAIL WWW   Вверх
v_enom
Дата 5.6.2009, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 11.10.2006

Репутация: нет
Всего: нет



спаибо, буду обмозговывать!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0565 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.