Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
16 / 0 / 2
Регистрация: 10.11.2012
Сообщений: 117
1

Перегрузка операторов и templates

02.06.2015, 01:10. Показов 1213. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый вечер!!

Разбираюсь дальше с классами и шаблонами. Никак не получается создать класс Матрица. Знаю, что в интернете полно решенных примеров, однако хочу разобраться набивая шишки по своему.

Вот такой класс:
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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#include <stdio.h>
#pragma hdrstop
 
//---------------------------------------------------------------------------
template <class T>
 class Array_2D
 {
  public:
    // constructor
    Array_2D(unsigned wd,unsigned ht) : nWd(wd), nHt(ht), pAr(0)
    {
      if(wd > 0 && ht > 0) pAr = new T[wd * ht];
    }
 
    // destructor
    ~Array_2D() { delete[] pAr ; }
 
   // indexing (parenthesis operator)
   //  two of them (for const correctness)
 
   const T& operator () (unsigned x,unsigned y) const
   {  return pAr[ y*nWd + x ];   }
 
   T& operator () (unsigned x,unsigned y)
   {  return pAr[ y*nWd + x ];   }
 
   // get dims
   unsigned GetRows()  const { return nWd; }
   unsigned GetColns() const { return nHt; }
 
  // оператор сложения
   friend Array_2D operator + (const Array_2D &A, const Array_2D &B);
 
 // private data members
 private:
   unsigned nWd;
   unsigned nHt;
   T*       pAr;
};
 
template <class F, class T, class R>
 Array_2D<F> operator + (const Array_2D<T> &A, const Array_2D<R> &B){
 
  Array_2D<F> C(B.GetRows(),B.GetRows()) ;
 
  for(unsigned i = 0 ; i < B.GetRows() ; ++i){
    for(unsigned j = 0 ; j < B.GetRows() ; ++j){
      C(i,j) = A(i,j) + B(i,j) ;
    }
  }
 
  return C ;
 }

Скажите, правильно ли я вообще делаю?

Выдает ошибку: [Linker Error] Unresolved external 'operator +(const Array_2D<int>&, const Array_2D<int>&)'.

Заранее благодарю за помощь!
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.06.2015, 01:10
Ответы с готовыми решениями:

Что такое "перегрузка операторов"? Каковы принципы работы перегруженных операторов и назначение указателя this
Добрый день . Помогите понять принцип работы перегрузки операторов. объясните пожалуйста в...

перегрузка операторов
Всем привет. Дошел до темы перегрузки операторов и возникло два вопроса. Первый: Чем отличается...

перегрузка операторов)
ожидаемо)))) правильно же? на этом ну просто нельзя не споткнуться . я думаю,что вы и следующие...

Перегрузка операторов
ifstream ifile(&quot;open.txt&quot;); if(! ifile) { } Как реализовать класс, что бы можно было...

19
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
02.06.2015, 07:16 2
Лучший ответ Сообщение было отмечено krazyd как решение

Решение

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
template <class T>
 class Array_2D
 {
  public:
    // constructor
    Array_2D(unsigned wd,unsigned ht) : nWd(wd), nHt(ht), pAr(0)
    {
      if(wd > 0 && ht > 0) pAr = new T[wd * ht];
    }
 
    Array_2D(const Array_2D& A) : nWd(A.nWd), nHt(A.nHt)
    {
       pAr = new T[nWd * nHt];
       for (int i = 0; i < nWd; ++i)
           for (int j = 0; j < nHt; ++j)
               (*this)(i, j) = A(i, j);
    }
 
    Array_2D& operator=(const Array_2D& A)
    {
       if (this != &A)
       {
           delete [] pAr;
           nWd = A.nWd;
           nHt = A.nHt;
           pAr = new T[nWd * nHt];
           for (int i = 0; i < nWd; ++i)
               for (int j = 0; j < nHt; ++j)
                   (*this)(i, j) = A(i, j);
       }
       return *this;
    }
    
    // destructor
    ~Array_2D() { delete [] pAr ; }
 
   // indexing (parenthesis operator)
   //  two of them (for const correctness)
 
   const T& operator () (unsigned x,unsigned y) const
   {  return pAr[ y*nWd + x ];   }
 
   T& operator () (unsigned x,unsigned y)
   {  return pAr[ y*nWd + x ];   }
 
   // get dims
   unsigned GetRows()  const { return nWd; }
   unsigned GetColns() const { return nHt; }
 
  // оператор сложения
  //friend Array_2D operator+ <T> (const Array_2D &A, const Array_2D &B);
 
 // private data members
 private:
   unsigned nWd;
   unsigned nHt;
   T*       pAr;
};
 
template <class T>
 Array_2D<T> operator + (const Array_2D<T> &A, const Array_2D<T> &B){
 
     Array_2D<T> C(B.GetRows(), B.GetColns()) ;
 
  for(unsigned i = 0 ; i < B.GetRows() ; ++i){
      for(unsigned j = 0 ; j < B.GetColns() ; ++j){
      C(i,j) = A(i,j) + B(i,j) ;
    }
  }
 
  return C ;
 }
1
16 / 0 / 2
Регистрация: 10.11.2012
Сообщений: 117
02.06.2015, 14:47  [ТС] 3
Благодарю вас!

Правильно ли я понимаю, что оператор + будет работать для объектов только одного типа?
0
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
02.06.2015, 18:14 4
Цитата Сообщение от krazyd Посмотреть сообщение
Правильно ли я понимаю, что оператор + будет работать для объектов только одного типа?
Собираешься массивы разных типов складывать?
1
16 / 0 / 2
Регистрация: 10.11.2012
Сообщений: 117
02.06.2015, 18:49  [ТС] 5
Да. int и double возможно.
0
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
02.06.2015, 18:50 6
И какой смысл в этом?
1
16 / 0 / 2
Регистрация: 10.11.2012
Сообщений: 117
02.06.2015, 19:15  [ТС] 7
Разные случаи бывают. Разве это плохо?
0
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
02.06.2015, 19:19 8
Цитата Сообщение от krazyd Посмотреть сообщение
Разве это плохо?
А что хорошего? Если double будешь складывать с int, что от double останется? Какой смысл тогда в этом double? Какие случаи? Как напишешь, так и будет.
1
16 / 0 / 2
Регистрация: 10.11.2012
Сообщений: 117
02.06.2015, 19:22  [ТС] 9
А разве type casting для int не произойдет?
0
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
02.06.2015, 19:42 10
Цитата Сообщение от krazyd Посмотреть сообщение
А разве type casting для int не произойдет?
Если int-у double присваивать?
1
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
02.06.2015, 19:56 11
Цитата Сообщение от lss Посмотреть сообщение
Если double будешь складывать с int, что от double останется?
Можно предоставить этот выбор компилятору. Если добавить еще один оператор, наподобие:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <class T1, class T2>
 Array_2D<typename std::common_type<T1, T2>::type> 
      operator + (const Array_2D<T1> &A, const Array_2D<T2> &B){
 
     Array_2D<typename std::common_type<T1, T2>::type> C(B.GetRows(), B.GetColns()) ;
 
  for(unsigned i = 0 ; i < B.GetRows() ; ++i){
      for(unsigned j = 0 ; j < B.GetColns() ; ++j){
      C(i,j) = A(i,j) + B(i,j) ;
    }
  }
 
  return C ;
 }
1
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
02.06.2015, 19:58 12
Цитата Сообщение от lss Посмотреть сообщение
Если double будешь складывать с int, что от double останется?
double + int == double?
1
16 / 0 / 2
Регистрация: 10.11.2012
Сообщений: 117
02.06.2015, 20:01  [ТС] 13
И как тогда это будет выглядить в моем варианте? T1 будет типом класса?
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
02.06.2015, 20:02 14
Цитата Сообщение от krazyd Посмотреть сообщение
И как тогда это будет выглядить в моем варианте? T1 будет типом класса?
Так и будет.
1
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
02.06.2015, 20:02 15
еще вроде как в новом стандарте есть возможность в компайл тайме определить тип результата сложения T1 + T2.
подробностей правда не знаю.
но в варианте, когда он в компайл тайме определяется могут возникнуть проблемы с кодом. там то результат
в переменные определенного типа складываются и их тип может отличатся от типа, который вывел компилятор.
в результате будут или ошибки компиляции, или незаметные рантайм преобразования одного типа массива в другой, что не есть гуд.
1
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
02.06.2015, 20:03 16
Цитата Сообщение от Perfilov Посмотреть сообщение
еще вроде как в новом стандарте есть возможность в компайл тайме определить тип результата сложения T1 + T2.
подробностей правда не знаю.
C++
1
2
3
4
template <class T, class U>
auto add( T x, U y ) -> decltype( x + y ) {
    return x + y;
}
"Новый", это который от 2011-го года?
1
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
02.06.2015, 20:10 17
Цитата Сообщение от Perfilov Посмотреть сообщение
но в варианте, когда он в компайл тайме определяется могут возникнуть проблемы с кодом. там то результат
в переменные определенного типа складываются и их тип может отличатся от типа, который вывел компилятор.
Это как-то странно звучит. Не мог бы ты проиллюстрировать свое утверждение, чтобы исключить неправильное понимание этой фразы. В такой формулировке она выглядит спорно.
1
265 / 165 / 56
Регистрация: 25.02.2015
Сообщений: 435
02.06.2015, 20:23 18
C++
1
2
3
4
5
6
7
typedef Array<int> IntArr;
typedef Array<double> DoubleArr;
//вроде общий тип у них - double
//а в коде кто-то написал:
IntArr summ = IntArr() + DoubleArr();
// если тип результата - DoubleArr, то либо неявный каст DoubleArr в IntArr если он возможен,
// либо ошибка компиляции. Неявный каст может быть критичен в плане производительности.
2
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
02.06.2015, 20:34 19
Цитата Сообщение от Perfilov Посмотреть сообщение
если тип результата - DoubleArr, то либо неявный каст DoubleArr в IntArr если он возможен, либо ошибка компиляции. Неявный каст может быть критичен в плане производительности.
Теперь понятно. Согласен. Пользователь написал один тип, а вывелся другой -> каст.
Сперва я про другое подумал.
1
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
02.06.2015, 20:47 20
Цитата Сообщение от Perfilov Посмотреть сообщение
вроде общий тип у них - double
Может я чего-то не понимаю, но почему общий тип у них double?
1
02.06.2015, 20:47
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.06.2015, 20:47
Помогаю со студенческими работами здесь

перегрузка операторов
Есть перечисление и функция : enum Num { on, tw, th, fo ,fi, si ,se, ei, ni ,last }; Num...

Перегрузка операторов С++
Задание: Написать код на языке С++ где реализуется перегрузка операторов. Тематика: База данных...

Перегрузка операторов << и >>
Добрый вечер! Задание состоит в следующем: необходимо изменить интерфейс методов Print и Read:...

Перегрузка операторов
Я тут пока изучаю перегрузку, написал следующий код: class String{ private: size_t size_;...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru