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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Простейший шаблон, в чем ошибка? 
:(
    Опции темы
EvgenZ
Дата 3.8.2006, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Freedom in me
**


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

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



Знаю, что все просто, но сообразить не могу. Объясните пожалуйста где ошибка и из-за чего. Как исправить...

Код

#include <iostream>
class Animal{
public:
    Animal():mAge(0),mWeigh(0){}
    Animal(int Age, int Weigh): mAge(Age), mWeigh(Weigh){}
    ~Animal(){}
    int GetAge()const {return mAge;}
    void SetAge(int Age){mAge=Age;}
    int GetWeigh()const {return mWeigh;}
    void SetWeigh(int Weigh){mWeigh=Weigh;}
    friend std::ostream& operator<< (std::ostream&, Animal&);
private:
    int mAge;
    int mWeigh;
};

std::ostream& operator<<(std::ostream& Astream, Animal& Ani){
    Astream << Ani.GetAge();
    Astream << Ani.GetWeigh();
    std::cout<<"Animal<<";
return Astream;
}

template <class T>
class Array{
public:
    Array(int Size=5);
    Array(const Array&);
    ~Array(){delete [] pTipe; }
    Array& operator=( Array&);
    int GetSize(){return mSize;}
    void SetSize(int Size){mSize=Size;}
    template <class T>
    friend std::ostream& operator<< (std::ostream&, Array<T>&);
private:
    int mSize;
    T *pTipe;
};
template <class T>
Array<T>::Array(int Size): mSize(Size){
    pTipe=new T[Size];
    for(int i=0;i<Size;i++) 
        pTipe[i]=0;}

template <class T>
Array<T>::Array( Array& rhs){
mSize = rhs.GetSize();
pTipe = new T[mSize];
for(int i=0;i<rhs.GetSize();i++)
   pTipe[i]=rhs[i];
}

template <class T>
Array<T>& Array<T>::operator=( Array<T>& rhs){
if(this==&rhs)
   return *this;
delete [] pTipe;
mSize = rhs.GetSize();
pTipe= new T[Size];
for(int i=0;i<mSize;i++)
   pTipe[i]=rhs[i];
return *this;
}

template <class T>
std::ostream& operator<< (std::ostream& ArStream, Array<T>& Arr){
for(int i=0;i<Arr.GetSize();i++)
   ArStream << Arr[i];
std::cout<<"template <<";
return ArStream;
}

void zapolnenieInt(Array<int>& Arr){
    for(int i=0;i<5;i++)
        Arr[i]=i*5;
}

void zapolnenieAnimal(Array<Animal>& Arr){
Animal *pAni;
  for(int i=0;i<Arr.GetSize();i++){
     pAni=new Animal(i*10);
     Arr[i]=*pAni;
     delete pAni;
     }
} 

int main(){

Animal a;
Array<int> b;
std::cout<<a<<std::endl;
zapolnenieInt(b);
std::cout<<b;
return 0;
}


компилятор VS2005    smile  smile 


--------------------
<удалено администрацией форума>
PM MAIL   Вверх
Void
Дата 3.8.2006, 18:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

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



Сколько секунд ты сэкономил, не набирая пробелы в коде, и сколько потерял я, пытаясь в нём разобраться…

Ошибки:
1) Сигнатура определения конструктора класса Array не соответствовала его объявлению (отсутствовал const).
2) Попытка обращаться к объектам типа Array, как a[index], не определив оператор [] или оператор преобразования к T*.
3) В функции zapolnenieAnimal производится попытка создания объекта типа Animal с одним параметром типа int, в то время как у этого класса есть конструктор без параметров и конструктор с двумя параметрами типа int.

Код с исправлениями:
Код
#include <iostream>
#include <cassert>

class Animal {
public:
    Animal():mAge(0),mWeigh(0){}
    Animal(int Age, int Weigh): mAge(Age), mWeigh(Weigh){}
    ~Animal(){}
    int GetAge()const {return mAge;}
    void SetAge(int Age){mAge=Age;}
    int GetWeigh()const {return mWeigh;}
    void SetWeigh(int Weigh){mWeigh=Weigh;}
    friend std::ostream& operator<< (std::ostream&, Animal&);
private:
    int mAge;
    int mWeigh;
};

std::ostream& operator<<(std::ostream& Astream, Animal& Ani) {
    Astream << Ani.GetAge();
    Astream << Ani.GetWeigh();
    std::cout<<"Animal<<";
    return Astream;
}

template <class T>
class Array {
public:
    Array(int Size=5);
    Array(const Array&);
    ~Array(){delete [] pTipe; }
    Array& operator=( Array&);
    int GetSize(){return mSize;}
    void SetSize(int Size){mSize=Size;}
    T &operator [](int index);
    const T &operator [](int index) const;
    template <class T>
    friend std::ostream& operator<<(std::ostream&, Array<T>&);
private:
    int mSize;
    T *pTipe;
};

template <class T>
Array<T>::Array(int Size) : mSize(Size) {
    pTipe=new T[Size];
    for(int i=0;i<Size;i++) 
        pTipe[i]=0;
}

template <class T>
Array<T>::Array(const Array& rhs) {
    mSize = rhs.GetSize();
    pTipe = new T[mSize];
    for(int i=0;i<rhs.GetSize();i++)
        pTipe[i]=rhs[i];
}

template <class T>
Array<T>& Array<T>::operator=(Array<T>& rhs) {
    if(this==&rhs)
        return *this;
    delete [] pTipe;
    mSize = rhs.GetSize();
    pTipe= new T[Size];
    for(int i=0;i<mSize;i++)
        pTipe[i]=rhs[i];
    return *this;
}

template <class T>
T& Array<T>::operator [](int index) {
    assert(index >= 0 && index < mSize);
    return pTipe[index];
}

template <class T>
const T& Array<T>::operator [](int index) const {
    assert(index >= 0 && index < mSize);
    return pTipe[index];
}

template <class T>
std::ostream& operator<< (std::ostream& ArStream, Array<T>& Arr){
    for(int i=0;i<Arr.GetSize();i++)
        ArStream << Arr[i];
    std::cout<<"template <<";
    return ArStream;
}

void zapolnenieInt(Array<int>& Arr){
    for(int i=0;i<5;i++)
        Arr[i]=i*5;
}

void zapolnenieAnimal(Array<Animal>& Arr) {
    Animal *pAni;
    for(int i = 0; i < Arr.GetSize(); i++){
        pAni = new Animal(); // wtf?!
        Arr[i] =* pAni;
        delete pAni;
    }
} 

int main(){
    Animal a;
    Array<int> b;
    std::cout<<a<<std::endl;
    zapolnenieInt(b);
    std::cout<<b;
    return 0;
}



--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
EvgenZ
Дата 3.8.2006, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Freedom in me
**


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

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



Цитата

Попытка обращаться к объектам типа Array, как a[index], не определив оператор [] или оператор преобразования к T*.

 
это значит, что все шаблонные классы должны содержать оператор [] ? А зачем перегруженный const?

#include <cassert> - что такое?

Это сообщение отредактировал(а) EvgenZ - 3.8.2006, 18:49


--------------------
<удалено администрацией форума>
PM MAIL   Вверх
Void
Дата 3.8.2006, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

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



Цитата(EvgenZ @  3.8.2006,  20:40 Найти цитируемый пост)
это значит, что все шаблонные классы должны содержать оператор [] ?

Нет. Но в данном случае он необходим, так как объекты класса Array в коде используются в качестве массивов.
Цитата(EvgenZ @  3.8.2006,  20:40 Найти цитируемый пост)
#include <cassert> - что такое?

Заголовочный файл, подключённый для использования макроса assert. RTFM.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
EvgenZ
Дата 3.8.2006, 21:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Freedom in me
**


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

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



насчет assert я тупанул  smile , про классы-массивы вроде тоже понял, а вот зачем const [] и просто [] непойму.


--------------------
<удалено администрацией форума>
PM MAIL   Вверх
Void
Дата 3.8.2006, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

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



Цитата(EvgenZ @  3.8.2006,  23:57 Найти цитируемый пост)
а вот зачем const [] и просто [] непойму. 

Без варианта с const компилятор не даст вызвать оператор для константного массива. Например, не скомпилируется такой код:
Код
int sum(const Array<int>& a) {
    int result = 0;
    for (int i = 0; i < a.GetSize(); ++i)
        result += a[i];
    return result;
}

Кстати, GetSize в том случае тоже надо сделать константным. Вообще, не надо пренебрегать const: если метод не изменяет состояние объекта, надо делать его константным.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
GePo
Дата 3.8.2006, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 30.3.2003
Где: Москва

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



Цитата(Void @ 3.8.2006,  23:02)
Цитата(EvgenZ @  3.8.2006,  23:57 Найти цитируемый пост)
а вот зачем const [] и просто [] непойму. 

Без варианта с const компилятор не даст вызвать оператор для константного массива. 

Void, наверное это был вопрос про лишнюю перегрузку оператора []. Посмотри в код, если оставить одну константную перегрузку оператора, то и для обычного объекта метод будет работать.
EvgenZ, естественно, можно оставить только одну константную перегрузку.
--------------------
PM MAIL WWW   Вверх
Void
Дата 3.8.2006, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

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



GePo, семантика Array подразумевает необходимость обоих вариантов. Если один из них (или оба) не используются в данной конкретной программе, это ничего не значит.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
GePo
Дата 3.8.2006, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 30.3.2003
Где: Москва

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



Void, извнияюсь, не доглядел. Если я правильно понял, то под особенностью семантики подразумевается разница в возращаемых типах функциями - в одном случае - ссылка на объект, во-втором - ссылка на константный объект. ( это все-таки для ответа на вопрос EvgenZ)
--------------------
PM MAIL WWW   Вверх
EvgenZ
Дата 3.8.2006, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Freedom in me
**


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

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



Спасибо большое, у меня была мыслишка написать operator[], но я совершенно не подумал про const []. 


--------------------
<удалено администрацией форума>
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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