Форум программистов, компьютерный форум CyberForum.ru

Шаблоны - C++

Восстановить пароль Регистрация
 
Shepard90
5 / 5 / 0
Регистрация: 18.10.2010
Сообщений: 140
23.06.2011, 16:33     Шаблоны #1
Не могу понять в чем косяк. Компилятор ругается на перегрузке оператора ввода
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// Lab1-var3.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <conio.h>
#include <string.h>
#include <assert.h>
#include <iostream>
using namespace std;
 
 
 
template <typename T>
class Arr
{
    // Оператор вывода
    friend ostream &operator<<(ostream &, const Arr<T> &);
    // Оператор ввода
    friend istream &operator>>(istream &, Arr<T> &);
    public:
        Arr(int = 5);
        // Конструктор
        Arr(const Arr&);
        // Деструктор
        ~Arr();
        // Размер
        int GetSize() const;
        // Присваивание
        const Arr &operator = (T);
        // ==
        bool operator ==(const Arr &) const;
        // !=
        bool operator !=(const Arr &) const;
        // Доступ к элементам
        T &operator[](int);
        static int GetCount();
    private:
        T *Ptr; //указатель на 1-ый элемент
        int Size; //размер массива
        static int ArrCount; //подсчитывает количество экземпляров класса
};
template <typename T>
int Arr<T>::ArrCount = 0;
 
// Создаем массив
 
template <typename T>
Arr<T>::Arr(int ArrSize) //конструктор с параметром размер массива
{
    ++ArrCount;//увеличение на 1
    Size = ArrSize; //присваивание переменной класса параметра ф-ция
    Ptr = new T[Size]; //в области динамического обмена выделяем память под массив (Ptr - указатель на начало массива)
    assert(Ptr != 0);
    for (int I = 0; I < Size; I++)// заполняем массив нулями
        Ptr[I] = 0; 
}
 
// Создаем массив
template <typename T>
Arr<T>::Arr(const Arr<T>&init) //копировщик
{
    ++ArrCount;//увеличение на 1
    Size = init.Size; //приравниваем размер существующего массива к создаваемому
    Ptr = new double[Size]; //выделяем для нового массива участок памяти
    assert(Ptr != 0); 
    for (int I = 0; I < Size; I++)
        Ptr[I] = init.Ptr[I]; //копируем элементы
}
 
// Разрушаем наш массив
template <typename T>
Arr<T>::~Arr() //деструктор, который уменьшает количестиво массивов на 1 (команда --ArrCount) и очищает участок памяти, на которую указывает Ptr
{
    --ArrCount; //уменьшение на 1
    delete []Ptr; // удаление данных из участка памяти, на который указывает Ptr 
}
 
// Размер
template <typename T>
int Arr<T>::GetSize() const //метод выводит размер массива 
{
    return Size; //вывод размера в качестве возвращаемого значения ф-ции метода
}
 
// Присваивание
template <typename T>
const Arr<T> &Arr<T>::operator = (T Right)//присвоение всем элементам массива значения Right
{
    Ptr = new double[Size];
    assert(Ptr != 0);
    for (int I = 0; I < Size; I++)
        Ptr[I] = Right;
    return *this;
}
template <typename T>
T &Arr<T>::operator[](int I)//вывод элемента массива по индексу I
{
    // Получаем позицию элемента
    assert(0 <= I&&I < Size);
    return Ptr[I];
}
template <typename T>
int Arr<T>::GetCount() // вывод количества массивов
{
    // Получаем размер массива
    return ArrCount;
}
 
// Ввод
template <typename T>
istream &operator>>(istream &Input, Arr<T> &A)//перегружаем оператор ввода
{
    for (int I = 0; I < A.Size; I++)
        Input>>A.Ptr[I];
    return Input;
}
 
// Вывод
template <typename T>
ostream &operator<<(ostream &Output, const Arr<T> &A)
{
    int I;
    for (I = 0; I < A.Size; I++)
        Output<<A.Ptr[I]<<" ";
    if ((I + 1) % 10 == 0)
        Output<<endl;
    return Output;
}
 
// ==
template <typename T>
bool Arr<T>::operator ==(const Arr<T> &Right) const //ф-ция-оператор результатом которого будет вывод истина или ложь
{
    bool B = true;
    for (int I = 0; I < Size; I++) //в цикле поэлементно сравноиваем два массива( а именно тот для объекта которого вызван метод и Right)
        if (Ptr[I] != Right.Ptr[I])//если одноименные элементы не равны то выход из цикла
        {
            B = false;
            break; //выход из цикла
        }
    return B;
}
 
// !=
template <typename T>
bool Arr<T>::operator !=(const Arr<T> &Right) const // обратный предыдущему - проверка на неравенство
{
    bool B = true;
    for (int I = 0; I < Size; I++)
        if (Ptr[I] == Right.Ptr[I])
        {
            B = false;
            break;
        }
    return B;
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    int A;
    // Создаем объекты массивов
    Arr<int> Arr1(5);
    Arr<int> Arr2;// создаем два массива размерностью 5. размер второго задается по умолчанию
    // Вводим 10 элементов
    cout<<"Enter 10 Number :"<<endl; 
    cin>>Arr1>>Arr2; // вводим сначала элементы первого массива, потом второго
    // ==
    if (Arr1 == Arr2) //сравниваем массивы 
        cout<<"Arr1 == Arr2"<<endl;
    if (Arr1 != Arr2)
        cout<<"Arr1 != Arr2"<<endl;
    // Доступ по индексу
    cout<<"Enter A For [] :"<<endl; 
    cin>>A;
    cout<<"[] = "<<Arr1[A]<<endl; //выполняем обращение по индексу к элементу первого массива
    _getch();
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
pito211
 Аватар для pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
23.06.2011, 16:36     Шаблоны #2
объяснить чё к чему не смогу, но знаю как исправить - в определение класса перенеси
это
C++
1
2
3
4
5
6
friend istream &operator>>(istream &Input, Arr<T> &A)//перегружаем оператор ввода
    {
        for (int I = 0; I < A.Size; I++)
            Input>>A.Ptr[I];
        return Input;
    }
Shepard90
5 / 5 / 0
Регистрация: 18.10.2010
Сообщений: 140
23.06.2011, 16:42  [ТС]     Шаблоны #3
Работает Спасибо!
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
23.06.2011, 17:32     Шаблоны #4
Ну тогда вот ещё два варианта (на абстрактном примере)
Первый мне не нравится.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
template <typename T> class A;
template <typename T> std::ostream& operator<< (std::ostream&, A<T> const&);
template <typename T> std::istream& operator>> (std::istream&, A<T>&);
 
template <typename T>
class A
{
    T v;
    friend std::ostream& operator<< <>(std::ostream&, A const&);
    friend std::istream& operator>> <>(std::istream&, A&);
public:
    A() : v(0) {}
    A(T const& v_) : v(v_) {}
};
 
template <typename T>
inline
std::ostream& operator<< (std::ostream& out, A<T> const& a)
{
    return (out << a.v);
}
 
template <typename T>
inline
std::istream& operator>> (std::istream& in, A<T>& a)
{
    return (in >> a.v);
}
Второй — без использования друзей.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
template <typename T>
class A
{
    T v;
public:
    A() : v(0) {}
    A(T const& v_) : v(v_) {}
    std::ostream& StreamOutput(std::ostream& out) const
        { return (out << v); }
    std::istream& StreamInput(std::istream& in)
        { return (in >> v); }
};
 
template <typename T>
inline
std::ostream& operator<< (std::ostream& out, A<T> const& a)
{
    return a.StreamOutput(out);
}
 
template <typename T>
inline
std::istream& operator>> (std::istream& in, A<T>& a)
{
    return a.StreamInput(in);
}
И это... Шаблонные функции надо бы объявлять как inline (ну или внутри определения класса)
sandye51
программист С++
 Аватар для sandye51
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
23.06.2011, 17:57     Шаблоны #5
grizlik78, чето ты перемудрил) и зачем ссылка на константу? Оо

Добавлено через 8 минут
Цитата Сообщение от grizlik78 Посмотреть сообщение
template <typename T> std::ostream& operator<< (std::ostream&, A<T> const&);
Цитата Сообщение от grizlik78 Посмотреть сообщение
friend std::ostream& operator<< <>(std::ostream&, A const&);
чето я вперые вижу подобную запись. Можно прокомментировать связь этих 2х строк?
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
23.06.2011, 18:00     Шаблоны #6
Цитата Сообщение от sandye51 Посмотреть сообщение
и зачем ссылка на константу?
Ссылка чтобы лишний раз объекты не копировать (да и не всегда конструктор копирования открытый), а на константу чтобы можно было константные объекты выводить. Типа
C++
1
2
3
4
void Func(A<int> const& a)
{
    std::cout << a << std::endl;
}
Да и потом это обычный вид оператора <<. Вон и у ТС тоже ссылка на константу.

Добавлено через 2 минуты
Цитата Сообщение от sandye51 Посмотреть сообщение
чето я вперые вижу подобную запись. Можно прокомментировать связь этих 2х строк?
Первая объявляет шаблонную функцию. А <> при объявлении дружественной функции говорит что она тоже является шаблонной. Но, если честно, я тоже до конца не понимаю этой магии
sandye51
программист С++
 Аватар для sandye51
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
23.06.2011, 18:00     Шаблоны #7
grizlik78, у ТС константная ссыла, а не ссылка на константу
т.е.
C++
1
const T& buffer
а не
C++
1
T const& buffer
как бы обычно первый вариант используют
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
23.06.2011, 18:02     Шаблоны #8
sandye51, эти две строки абсолютно эквивалентны. Обе ссылка на константу. Мне нравится второй вариант. Не путать с действительно константной ссылкой:
C++
1
T& const buffer
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
23.06.2011, 18:06     Шаблоны #9
sandye51, ссылки и так константые (их же нельзя переопределить). А обе твои записи равнозначные, это ссылки на константу.

опоздал...

Добавлено через 1 минуту
Цитата Сообщение от grizlik78 Посмотреть сообщение
C++
1
T& const buffer
вроде как нынче такое не используется...
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
23.06.2011, 18:11     Шаблоны #10
Цитата Сообщение от Kastaneda Посмотреть сообщение
вроде как нынче такое не используется...
Я даже компилировать такое не пробовал. Вдруг такое даже не компилится? Но если ссылку заменить указателем, то сказанное обретает смысл.
А так да, ссылки и так константные.
Kastaneda
23.06.2011, 18:13
  #11

Не по теме:

Цитата Сообщение от grizlik78 Посмотреть сообщение
Вдруг такое даже не компилится?
VS 2010
Код
 warning C4227: устаревший элемент: пропуск квалификаторов для ссылки

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.06.2011, 18:15     Шаблоны
Еще ссылки по теме:

Шаблоны C++
C++ Шаблоны
Шаблоны C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
sandye51
программист С++
 Аватар для sandye51
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
23.06.2011, 18:15     Шаблоны #12
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void F(int& const a)
{
    std::cout << a << std::endl;
}
 
void F1(const int& const a)
{
    std::cout << a << std::endl;
}
 
int main()
{
    const int a = 5;
    int b = 5;
    // F(a); не компилит;
    F(b); // компилит;
    F1(a); // компилит;
 
    _getch();
    return EXIT_SUCCESS;
}
работает, но warning на const после &
Код
warning C4227: anachronism used : qualifiers on reference are ignored
Yandex
Объявления
23.06.2011, 18:15     Шаблоны
Ответ Создать тему
Опции темы

Текущее время: 07:05. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru