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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 35, средняя оценка - 4.83
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
#1

Абстрактный шаблонный класс - C++

26.09.2010, 03:22. Просмотров 4590. Ответов 45
Метки нет (Все метки)

Вообщем какое дело. У меня есть класс матрица, который сделан с использованием шаблонов и STL. В нем перегружены операторы ввода/вывода в поток(то, что их не врубить в динамический полиморфизм я уже понял).

Первый класс:

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
    //Класс матрицы
    template<class T>
    class Matr
    {
    public:
       Matr();
       Matr(size_t n, size_t m);
       Matr(const Matr&);
       virtual ~Matr();
       void SetSize(size_t n, size_t m);
       const size_t GetRow() const {return Matrix.size();}
       const size_t GetCol() const {return Matrix[0].size();}
       template<class T2>
       friend std::ostream& operator <<(std::ostream& os, const Matr<T2>& Ob);
       template<class T2>
       friend std::istream& operator >>(std::istream& is, Matr<T2>& Ob);
       Matr<T>& operator =(const Matr&);
       Matr<T> operator +=(const Matr&);
       Matr<T> operator +(const Matr&);
       Matr<T> operator *=(const Matr&);
       Matr<T> operator *(const Matr&);
       void random_fill();
    protected:
       std::vector<std::vector<T> > Matrix;
    };
Определение функций писать не буду, пока это не нужно. Вряд ли 200 строк чем-то помогут. Виртуальными эту перегрузку не сделать. И если я пишу второй код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
template<class T>
class ConsoleMatr:public Matr<T>
{
public:
   ConsoleMatr():Matr() {}
   ConsoleMatr(size_t n, size_t m):Matr(n, m) {}
   ConsoleMatr(const Matr& Ob):Matr(Ob) {}
   template<class T2>
   friend std::ostream& operator <<(std::ostream& os, const ConsoleMatr<T2>& Ob);
   template<class T2>
   friend std::istream& operator >>(std::istream& is, ConsoleMatr<T2>& Ob);
};
И комментирую эти методы в исходном классе, то как реализовать динамический полиморфизм?

Пробую так.
C++
1
2
3
4
5
6
7
8
typedef std::auto_ptr<Matr<int> > MatrSP;
 
int main()
{
   MatrSP Ob(new ConsoleMatr);
   std::cin>>Ob;
   //
}
Пишет ошибку. Впринципе это понятно. Тогда вопрос, как реализовать??

А так же есть вариант оставить оба варианта. Но будут вызываться операторы ввода/вывода из класса Matr.

И следующий вопрос. Добавляю в первый класс две чисто виртуальные функции. Класс принимает вид:

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
    //Класс матрицы
    template<class T>
    class Matr
    {
    public:
       Matr();
       Matr(size_t n, size_t m);
       Matr(const Matr&);
       virtual ~Matr();
       void SetSize(size_t n, size_t m);
       const size_t GetRow() const {return Matrix.size();}
       const size_t GetCol() const {return Matrix[0].size();}
       template<class T2>
       friend std::ostream& operator <<(std::ostream& os, const Matr<T2>& Ob);
       template<class T2>
       friend std::istream& operator >>(std::istream& is, Matr<T2>& Ob);
       Matr<T>& operator =(const Matr&);
       Matr<T> operator +=(const Matr&);
       Matr<T> operator +(const Matr&);
       Matr<T> operator *=(const Matr&);
       Matr<T> operator *(const Matr&);
       void random_fill();
           virtual void input()=0;
           virtual void output()=0;
    protected:
       std::vector<std::vector<T> > Matrix;
    };
А второй.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template<class T>
class ConsoleMatr:public Matr<T>
{
public:
   ConsoleMatr():Matr() {}
   ConsoleMatr(size_t n, size_t m):Matr(n, m) {}
   ConsoleMatr(const Matr& Ob):Matr(Ob) {}
   template<class T2>
   friend std::ostream& operator <<(std::ostream& os, const ConsoleMatr<T2>& Ob);
   template<class T2>
   friend std::istream& operator >>(std::istream& is, ConsoleMatr<T2>& Ob);
   void input();
   void output();
};
Вот так впринципе вполне неплохо идет полиморфизм. Но есть одно НО...

Ошибка происходит в этой функции.

C++
1
2
3
4
5
6
7
    template<class T>
    Matr<T> Matr<T>::operator *(const Matr<T> &Ob)
    {
          Matr<T> Obj(*this);   
          Obj*=Ob;
          return Obj;
    }
Нельзя инстанцинировать абстрактный класс... Что тоже понятно... Но непонятно, как тогда это реализовать. Или же забить на это и оставить как есть?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.09.2010, 03:22     Абстрактный шаблонный класс
Посмотрите здесь:

Шаблонный класс - C++
Я запутался с шаблонами. Не пойму никак как вызвать конструктор с введенным в функции check_int() значением и как дальше вызвать функции...

Шаблонный класс - C++
Ребят, прошу Вашей помощи.. Программу я написала.. Она работает. Но теперь мне нужно переделать ее , используя шаблонный класс. Я...

Шаблонный класс - C++
#include &lt;iostream&gt; using namespace std; template &lt;class T&gt; class Vector{ private: int size, capacity; T* data; public: ...

Шаблонный класс - C++
День добрый. Пишу матричный калькулятор на шаблонном классе. Хочу добиться того, чтобы можно было оперировать с матрицами всех численных...

Шаблонный класс - C++
Подскажите как указать реализацию методов для шаблонного класса template &lt;class T_machine&gt; class hospital_room { ...

шаблонный класс - C++
реализован согласно &quot;Создание конструкторов и деструктора&quot; на шаблон класса с параметром -Тип данных в файле, редактируется (байт / слово /...

Шаблонный класс - C++
Как его реализовать??? Смысл я понимаю, но вот как записать...не знаю:cry:

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Mr.X
Эксперт С++
3048 / 1693 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
28.09.2010, 12:43     Абстрактный шаблонный класс #31
Цитата Сообщение от Lavroff Посмотреть сообщение
Нормальный код?
Вообще-то специалисты советуют предпочитать включение наследованию, как более слабую зависимость.
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
28.09.2010, 12:48  [ТС]     Абстрактный шаблонный класс #32
Mr.X, Верю. Но мне нужно именно наследование в данной задаче.
Mr.X
Эксперт С++
3048 / 1693 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
28.09.2010, 12:53     Абстрактный шаблонный класс #33
Цитата Сообщение от alexzak Посмотреть сообщение
operator += и operator *= должны возвращать ConsoleMatr<T>&
Скорее const ConsoleMatr<T>&, так как эти операторы не должны возвращать l-value.
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
28.09.2010, 19:47  [ТС]     Абстрактный шаблонный класс #34
Итак... Я вообщем-то все изменил. Все работает впринципе.
Matrix.h

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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
#ifndef _MATRIX_H_
#define _MATRIX_H_
 
namespace MatrSpace
{
    //Matrix container class
    template<class T>
    class AbstractMatr
    {
    public:
        AbstractMatr() {}
        AbstractMatr(size_t n, size_t m);
        AbstractMatr(const AbstractMatr&);
        virtual ~AbstractMatr() {}
        void SetSize(size_t n, size_t m);
        inline const size_t GetRow() const {return Matrix.size();}
        inline const size_t GetCol() const {return Matrix[0].size();}
        void swap(AbstractMatr&);
    protected:
        std::vector<std::vector<T> > Matrix;
    };
 
    //Math Matr. public from AbstractMatr
    template<class T>
    class MathMatr:public AbstractMatr<T>
    {
    public:
        MathMatr():AbstractMatr() {}
        MathMatr(size_t n, size_t m):AbstractMatr<T>(n, m) {}
        MathMatr(const AbstractMatr<T>& Ob):AbstractMatr<T>(Ob) {}
        virtual ~MathMatr() {}
        const MathMatr<T>& operator =(const MathMatr&);
        const MathMatr<T>& operator +=(const MathMatr&);
        const MathMatr<T> operator +(const MathMatr&) const;
        const MathMatr<T>& operator *=(const MathMatr&);
        const MathMatr<T> operator *(const MathMatr&) const;
        virtual void input(std::istream&) {}
        virtual void output(std::ostream&) const {}
        template<class T2>
        friend std::ostream& operator <<(std::ostream&, const MathMatr<T2>& Ob);
        template<class T2>
        friend std::istream& operator >>(std::istream&, MathMatr<T2>& Ob);
        void random_fill();
    };
 
    //InOutMatr class. Public from MathMatr
    template<class T>
    class IOMatr:public MathMatr<T>
    {
    public:
        IOMatr():MathMatr<T>() {}
        IOMatr(size_t n, size_t m):MathMatr(n, m) {}
        IOMatr(const AbstractMatr<T>& Ob):MathMatr(Ob) {}
        virtual ~IOMatr() {}
        virtual void input(std::istream&)=0;
        virtual void output(std::ostream&) const=0;
    };
 
    //Console InOut public from IOMatr
    template<class T>
    class ConsoleMatr:public IOMatr<T>
    {
    public:
        ConsoleMatr():IOMatr<T>() {}
        ConsoleMatr(size_t n, size_t m):IOMatr(n, m) {}
        ConsoleMatr(const AbstractMatr<T>& Ob):IOMatr(Ob) {}
        virtual ~ConsoleMatr() {}
        const ConsoleMatr<T>& operator =(const ConsoleMatr&);
        const ConsoleMatr<T>& operator +=(const ConsoleMatr&);
        const ConsoleMatr<T> operator +(const ConsoleMatr&) const;
        const ConsoleMatr<T>& operator *=(const ConsoleMatr&);
        const ConsoleMatr<T> operator *(const ConsoleMatr&) const;
        virtual void input(std::istream&);
        virtual void output(std::ostream&) const;
    };
    
    //AbstractMatr func-members
    template<class T>
    AbstractMatr<T>::AbstractMatr(size_t n, size_t m)
    {
        Matrix.resize(n);
        for(int i=0; i!=GetRow(); ++i)
        {
            Matrix[i].resize(m);
        }
    }
 
    template<class T>
    AbstractMatr<T>::AbstractMatr(const AbstractMatr<T> &Ob)
    {
        *this=Ob;
    }
 
    template<class T>
    void AbstractMatr<T>::SetSize(size_t n, size_t m)
    {
        if(GetRow()!=0&&GetCol()!=0)
            Matrix.clear();
        Matrix.resize(n);
        for(int i=0; i!=GetRow(); ++i)
        {
            Matrix[i].resize(m);
        }
    }
 
    template<class T>
    void AbstractMatr<T>::swap(AbstractMatr<T>& Ob)
    {
        Matrix.swap(Ob.Matrix);
    }
    
    //MathMatr func-membets
    template<class T>
    const MathMatr<T>& MathMatr<T>::operator =(const MathMatr<T>& Ob)
    {
        MathMatr<T> Temp(Ob);
        Temp.swap(*this);
        return *this;
    }
 
    template<class T>
    const MathMatr<T>& MathMatr<T>::operator +=(const MathMatr<T>& Ob)
    {
        if(GetRow()!=Ob.GetRow()&&GetCol()!=Ob.GetCol())
            throw std::invalid_argument("Size of two matrix for sum must be equal!");
        for(int i=0; i!=Ob.GetRow(); ++i)
        {
           for(int j=0; j!=Ob.GetCol(); ++j)
           {
              Matrix[i][j]+=Ob.Matrix[i][j];
           }
        }
        return *this;
    }
 
    template<class T>
    const MathMatr<T> MathMatr<T>::operator +(const MathMatr<T>& Ob) const
    {
        MathMatr<T> Temp(*this);
        Temp+=Ob;
        return Temp;
    }
 
    template<class T>
    const MathMatr<T>& MathMatr<T>::operator *=(const MathMatr<T>& Ob)
    {
        if(GetCol()!=Ob.GetRow())
            throw std::invalid_argument("Num of 1-st matrix cols must be equal to num of 2-nd matrix rows");
        MathMatr Temp(GetRow(), Ob.GetCol());
        for(int i=0; i!=Temp.GetRow(); ++i)
        {
           for(int j=0; j!=Temp.GetCol(); ++j)
           {
              Temp.Matrix[i][j]=0;
              for(int k=0; k!=GetCol(); ++k)
              {
                 Temp.Matrix[i][j]+=Matrix[i][k]*Ob.Matrix[k][j];
              }
            }
        }
        *this=Temp;
        return *this;
    }
 
    template<class T>
    const MathMatr<T> MathMatr<T>::operator *(const MathMatr<T>& Ob) const
    {
        MathMatr<T> Temp(*this);
        Temp*=Ob;
        return Temp;
    }
 
    template<class T>
    void MathMatr<T>::random_fill()
    {
       for(int i=0; i!=GetRow(); ++i)
       {
          for(int j=0; j!=GetCol(); ++j)
          {
             Matrix[i][j]=1+rand()%50;
          }
       }
    }
 
    template<class T>
    std::ostream& operator <<(std::ostream& os, const MathMatr<T>& Ob)
    {
       Ob.output(os);
       return os;
    }
 
    template<class T>
    std::istream& operator >>(std::istream& is, MathMatr<T>& Ob)
    {
       Ob.input(is);
       return is;
    }
    
    //ConsoleMatr func-members
    template<class T>
    void ConsoleMatr<T>::input(std::istream& is)
    {
       for(int i=0; i!=GetRow(); ++i)
       {
          for(int j=0; j!=GetCol(); ++j)
          {
              std::cout<<"Enter Matrix ["<<i+1<<"]["<<j+1<<"]: ";
              is>>Matrix[i][j];
          }
       }
    }
 
    template<class T>
    void ConsoleMatr<T>::output(std::ostream& os) const
    {
       for(int i=0; i!=GetRow(); ++i)
       {
          for(int j=0; j!=GetCol(); ++j)
          {
              os<<std::setw(5)<<Matrix[i][j]<<' ';
          }
          std::cout<<std::endl;
       }
    }
 
    template<class T>
    const ConsoleMatr<T>& ConsoleMatr<T>::operator =(const ConsoleMatr<T>& Ob)
    {
        ConsoleMatr Temp(Ob);
        Temp.swap(*this);
        return *this;
    }
 
    template<class T>
    const ConsoleMatr<T>& ConsoleMatr<T>::operator +=(const ConsoleMatr<T>& Ob)
    {
        if(GetRow()!=Ob.GetRow()&&GetCol()!=Ob.GetCol())
           throw std::invalid_argument("Size of two matrix for sum must be equal!");
        for(int i=0; i!=Ob.GetRow(); ++i)
        {
           for(int j=0; j!=Ob.GetCol(); ++j)
           {
              Matrix[i][j]+=Ob.Matrix[i][j];
           }
        }
        return *this;
    }
 
    template<class T>
    const ConsoleMatr<T> ConsoleMatr<T>::operator +(const ConsoleMatr<T>& Ob) const
    {
        ConsoleMatr<T> Temp(*this);
        Temp+=Ob;
        return Temp;
    }
 
    template<class T>
    const ConsoleMatr<T>& ConsoleMatr<T>::operator *=(const ConsoleMatr<T>& Ob)
    {
        if(GetCol()!=Ob.GetRow())
            throw std::invalid_argument("Num of 1-st matrix cols must be equal to num of 2-nd matrix rows");
        ConsoleMatr Temp(GetRow(), Ob.GetCol());
        for(int i=0; i!=Temp.GetRow(); ++i)
        {
           for(int j=0; j!=Temp.GetCol(); ++j)
           {
              for(int k=0; k!=GetCol(); ++k)
              {
                 Temp.Matrix[i][j]+=Matrix[i][k]*Ob.Matrix[k][j];
              }
            }
        }
        *this=Temp;
        return *this;
    }
 
    template<class T>
    const ConsoleMatr<T> ConsoleMatr<T>::operator *(const ConsoleMatr<T>& Ob) const
    {
        ConsoleMatr<T> Temp(*this);
        Temp*=Ob;
        return Temp;
    }
}
#endif


Только...
C++
1
2
3
4
5
    template<class T>
    AbstractMatr<T>::AbstractMatr(const AbstractMatr<T> &Ob)
    {
        *this=Ob;
    }
Нормально-ли?
alexzak
84 / 57 / 1
Регистрация: 07.08.2010
Сообщений: 185
29.09.2010, 04:23     Абстрактный шаблонный класс #35
Цитата Сообщение от Lavroff Посмотреть сообщение
Итак... Я вообщем-то все изменил. Все работает впринципе.

Только...
C++
1
2
3
4
5
    template<class T>
    AbstractMatr<T>::AbstractMatr(const AbstractMatr<T> &Ob)
    {
        *this=Ob;
    }
Нормально-ли?
В копирующем конструкторе принято все что можно инициализировать в списке инициализации членов класса. Вот так:
C++
1
2
3
4
template <class T>
AbstractMatr<T>::AbstractMatr(const AbtractMatr<T> & Ob)
    : Matrix(Ob.Matrix)
{}
Добавлено через 13 минут
Цитата Сообщение от Mr.X Посмотреть сообщение
Скорее const ConsoleMatr<T>&, так как эти операторы не должны возвращать l-value.
Зачем возвращать const ConsoleMatr& ? Какой цели это служит? Если ориентироваться на стандартные классы и делать как в них сделано, то там возвращается просто по ссылке. Например, класс complex (http://cplusplus.com/reference/std/c...x/operators/):
C++
1
2
3
4
5
6
*** complex member functions: ***
complex<T>& operator= (const T& val);
complex<T>& operator+= (const T& val);
complex<T>& operator-= (const T& val);
complex<T>& operator*= (const T& val);
complex<T>& operator/= (const T& val);
А остальные операторы - просто по значению (тоже без const):
C++
1
2
*** global functions: ***
template<class T> complex<T> operator+(const complex<T>& lhs, const complex<T>& rhs);
Mr.X
Эксперт С++
3048 / 1693 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
29.09.2010, 17:09     Абстрактный шаблонный класс #36
Цитата Сообщение от alexzak Посмотреть сообщение
Зачем возвращать const ConsoleMatr& ? Какой цели это служит? Если ориентироваться на стандартные классы и делать как в них сделано, то там возвращается просто по ссылке. Например, класс complex (http://cplusplus.com/reference/std/c...x/operators/):
C++
1
2
3
4
5
6
*** complex member functions: ***
complex<T>& operator= (const T& val);
complex<T>& operator+= (const T& val);
complex<T>& operator-= (const T& val);
complex<T>& operator*= (const T& val);
complex<T>& operator/= (const T& val);
А остальные операторы - просто по значению (тоже без const):
C++
1
2
*** global functions: ***
template<class T> complex<T> operator+(const complex<T>& lhs, const complex<T>& rhs);
Ну, здесь я могу сослаться на книгу Скотта Майерса «Эффективное использование C++. 50 рекомендаций…», правило 21 которой называется «Везде, где только можно, используйте const». Там он приводит пример перегрузки оператора
const Rational operator*(const Rational& lhs, const Rational& rhs);
Он мотивирует здесь const тем, что иначе будут возможны вещи, которые он называет надругательством над здравым смыслом:
Rational a, b, c;

(a * b) = c;

Далее он пишет, что один из критериев хорошо определенного пользовательского типа – это отсутствие необоснованной несовместимости с поведением встроенных типов.
alexzak
84 / 57 / 1
Регистрация: 07.08.2010
Сообщений: 185
01.10.2010, 07:11     Абстрактный шаблонный класс #37
Цитата Сообщение от Mr.X Посмотреть сообщение
Ну, здесь я могу сослаться на книгу Скотта Майерса «Эффективное использование C++. 50 рекомендаций…», правило 21 которой называется «Везде, где только можно, используйте const».
Это то место, где он оказался неправ. Скотт Майерс не практик, а скорее "educator" (он изучает новые вещи, относящиеся к С++, а потом создаёт курсы для обучения других). И иногда он выдаёт вот такие "правила", которые с практической точки зрения неприменимы. Вот это его правило не прижилось. Как я помню его пообсуждали в свое время и забыли.
Mr.X
Эксперт С++
3048 / 1693 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
01.10.2010, 09:42     Абстрактный шаблонный класс #38
Цитата Сообщение от alexzak Посмотреть сообщение
Это то место, где он оказался неправ. Скотт Майерс не практик, а скорее "educator" (он изучает новые вещи, относящиеся к С++, а потом создаёт курсы для обучения других). И иногда он выдаёт вот такие "правила", которые с практической точки зрения неприменимы. Вот это его правило не прижилось. Как я помню его пообсуждали в свое время и забыли.
Ну вы уж поясните тогда, в чем он неправ-то. И в чем практическая неприменимость данного правила?
alexzak
84 / 57 / 1
Регистрация: 07.08.2010
Сообщений: 185
02.10.2010, 03:33     Абстрактный шаблонный класс #39
Цитата Сообщение от Mr.X Посмотреть сообщение
Ну вы уж поясните тогда, в чем он неправ-то. И в чем практическая неприменимость данного правила?
Так, понятно дело, в чём неприменимость. Майерс решил биться с ветряными мельницами. От чего он таким образом защищается, - пресловутое (a *= b) = c, - в коде редко когда встречается. А если такой код кто и напишет, то ничего страшного не будет. Всё продолжает работаеть как и предполагалось.

Поэтому в стандарте таких вещей нет. И в широко распостранённых С++ библиотеках тоже.
Mr.X
Эксперт С++
3048 / 1693 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
02.10.2010, 09:43     Абстрактный шаблонный класс #40
Цитата Сообщение от alexzak Посмотреть сообщение
Так, понятно дело, в чём неприменимость. Майерс решил биться с ветряными мельницами. От чего он таким образом защищается, - пресловутое (a *= b) = c, - в коде редко когда встречается. А если такой код кто и напишет, то ничего страшного не будет. Всё продолжает работаеть как и предполагалось.

Поэтому в стандарте таких вещей нет. И в широко распостранённых С++ библиотеках тоже.
Однако ж отсюда никак не следует, что Майерс неправ, и что его правило практически неприменимо. Тут скорее спор просто о вкусах. Поэтому ваша категоричность и безапелляционность при их обсуждении не совсем понятна. Мы же с Майерсом считаем, что следует приветствовать любые правила, ведущие к предотвращению ненужных взаимозависимостей, к большей понятности и предсказуемости кода.
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
02.10.2010, 23:57  [ТС]     Абстрактный шаблонный класс #41
Показал преподавателю эту прогу. Ему очень даже понравилось. Дал несколько советов по стилю. Один из советов меня ввел несколько в ступор.

Определение функций шаблонного класса принято делать в самом этом классе. Т.е. как-то так.

Я конечно доверяю профессионалу с 15-летним стажем на С/C++ и прочих языках программирования, но мне это кажется странным. Почему так принято, кто-то может объяснить?

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 <class T>
class Test
{
public:
    Test() 
    {
        a=0;
        b=0;
    }
    ~Test() {}
     Test(int a_, int b_)
     {
         a=a_;
         b=b_;
     }
     Test<T> operator +(const Test<T>& Ob) const
     {
          Test<T> Temp;
          Temp.a=a+Ob.a;
          Temp.b=b+Ob.b; 
          return Temp;
     }
private:
    int a;
    int b;
};
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
03.10.2010, 00:38     Абстрактный шаблонный класс #42
Lavroff, определение все-равно не отделимо от объявления (обычными способами), поэтому их разделение только усложнит код, видимо
в том же stl и у msvc, и у gcc все сплошняком
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
03.10.2010, 00:40  [ТС]     Абстрактный шаблонный класс #43
alex_x_x, Ну да. Если не брать в расчет экспорт шаблонов, который реализован только в одном компиляторе, и то насколько я понимаю криво.
Спасибо.
alexzak
84 / 57 / 1
Регистрация: 07.08.2010
Сообщений: 185
03.10.2010, 04:16     Абстрактный шаблонный класс #44
Цитата Сообщение от Lavroff Посмотреть сообщение
Определение функций шаблонного класса принято делать в самом этом классе.
Кто-то делает так, а кто-то и выносит из класса. Или можно маленькие функции в самом классе реализовывать, а большие вне. Когда вся реализация внутри класса, трудно увидеть интерфейс, так как он вперемешку с реализацией. Поэтому лучше не злоупотреблять сованием внутрь класса всего что можно.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.10.2010, 23:35     Абстрактный шаблонный класс
Еще ссылки по теме:

vector (шаблонный класс) - C++
Нужно создать простенький шаблонный класс вектор Подскажите пожалуйста , как написать запись элемента в начало вектора и в конец...

Шаблонный класс vector - C++
Всем привет. Помогите создать шаблонный класс vector и массив который хранит значения template&lt;typename T, size_t size&gt; class array{ ...

Дружественный шаблонный класс - C++
Доброго времени суток. Есть пример из книги (создание списка). Вот код: #ifndef LISTND_H #define LISTND_H template &lt;class...

Указатель на шаблонный класс - C++
Есть ли возможность инициализировать указатель на класс с шаблоном, но не указав при этом тип, ну т.е. написать не так Value_Class...

Шаблонный класс Стек - C++
прошу помочь разобраться с кодом. вопросы выделил по ходу кода. #ifndef _STACKNODE_H_ #define _STACKNODE_H_ #include &lt;string&gt; ...


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

Или воспользуйтесь поиском по форуму:
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
03.10.2010, 23:35     Абстрактный шаблонный класс #45
Цитата Сообщение от Lavroff Посмотреть сообщение
Показал преподавателю эту прогу. Ему очень даже понравилось. Дал несколько советов по стилю. Один из советов меня ввел несколько в ступор.

Определение функций шаблонного класса принято делать в самом этом классе. Т.е. как-то так.

Я конечно доверяю профессионалу с 15-летним стажем на С/C++ и прочих языках программирования, но мне это кажется странным. Почему так принято, кто-то может объяснить?
Это вроде бы из-за того,что не все компиляторы (по крайней мере,год назад) реализовывали директиву export для шаблонов,поэтому их нужно было всегда определять в заголовках.Вроде как оттуда пошло
И ещё возможно для того,чтобы шаблоны были доступны в момент копиляции. Если я что-то не так написал,профессионалы,поправьте,пожалуйста .
Lavroff, погляди в гугле ещё,там есть целая тема про это (ссылку давать не буду - зобанют )
Yandex
Объявления
03.10.2010, 23:35     Абстрактный шаблонный класс
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru