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

Overloading [] operators - C++

Восстановить пароль Регистрация
 
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
28.07.2012, 10:31     Overloading [] operators #1
Преект компилируется нормально. По заданию нужно чтобы было реализованно 2 версии оператора [] одна для чтения другая для записи
типа дано что нужно их декларироватьмплемн вот таким образом
Point& operator [] (int index);
const Point& operator [] (int index) const;

имплементацию надо сделать самому

ПРОБЛЕМА:
Я в имплементации добавил чтоб он мне выводим какой оператор вызывается для чтения или для записи. Вообщем каким то боком получается что тот который конст (для чтения ) вообще за проект не разу не вызывался. Что не так ?


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
//array.hpp // A header file for the Array class to your current project.
#ifndef Array_HPP
#define Array_HPP
 
#include "Point.hpp"
#include <iostream>
 
class Array
{
private:    
 
    Point* m_data;                  // A data member for a dynamic C array of Point objects (Point* m_data).
    int m_size;                     // A data member for the size of the array.
 
public: 
 
    //----------- Declaration of Constructors -----------//
    Array::Array();                         // Default constructor
    Array::Array(const int new_size);       // Constructor with size argument.
  
    //----------- Declaration of Modificator(s) member functions -----------//
    void   SetElement(const Point& pt, int index);          // Set Element to a Array object
 
 
    //----------- Declaration of Operators Overloading the class's members -----------//
    Array& operator =  (const Array& source);               // Overloading Assignment operator.
    Point& operator [] (int index);                         // Return a reference to needed m_data. Using for writing 
    const Point& operator [] (int index) const ;            // Return a reference to needed m_data. Using for reading
 
 
    //----------- Declaration of Global (friend) Ostream << Operator  -----------//
    friend std::ostream& operator << (std::ostream& os, const Array& ar);           // Overloading << operator
 
}   /*!!!*/; /*!!!*/
#endif // Array_HPP

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
#ifndef Point_HPP // anti multiply including gates
#define Point_HPP
 
#include <string>
#include <iostream>
#include <sstream>
 
class Point
{   
    private:        //  declaration of private data members 
    double x;       // X coordinate
    double y;       // Y coordinate
 
    public:         // public declaration of data members (in given example haven't ) and member functions 
 
 
        //----------- Declaration of Constructors -----------//
    Point();                                        // Default constructor
    Point(double newX , double newY);               // Constructor 
    explicit Point(double value /*, double newY*/);         // Second Constructor 
    Point (const Point& ObjectOfClassPoint);        //COPY constructor
    ~Point(); // 
 
    //----------- Declaration of  Accessors member functions -----------//
    std::string ToString() const;    
    double X() const;                   
    double Y() const;   
 
    //----------- Declaration and  of and Implementaion of setters member functions -----------//
    void X(double newX) {x = newX;};    // The x-coordinate
    void Y(double newY) {y = newY;};    // The y-coordinate
 
    //----------- Declaration of Global Ostream << Operator  -----------//
    friend std::ostream& operator << (std::ostream& out, Point const& ObjPoint); 
    friend std::ostream& operator << (std::ostream& out, Point const *objPoint);
    
}   /*!!!*/; /*!!!*/
 
//----------- Implementaion (inline) of getters member functions -----------//
 
inline  double Point::X() const {return x;};                    
inline  double Point::Y() const {return y;};    
 
#endif // Point_HPP

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
//Array.cpp
#include "Array.hpp"
                                        
    //----------- Implementation of Constructors -----------//
    Array::Array() :  m_size(10), m_data(new Point[m_size])                                    
            {
                std::cout << "Array Default Constructor was called " ;
            }
 
    Array::Array(const int new_size) :m_size(new_size), m_data(new Point[m_size])       //specified by the size input argument
                                    
            {   
 
                std::cout << "Array Constructor was called "; 
            }
 
    //----------- Declaration and  of Modificators member functions -----------//
    void Array::SetElement(const Point& ObjPoint, int index)
        {   
    
            if (index <= m_size) // When the index is out of bounds, ignore the “set”. 
            {
                m_data[index] = ObjPoint;
                std::cout << "Set Element " << ObjPoint  << std::endl;
            }
            else 
                std::cout << "The Element with index [ "<< index << " ] and\ndata ( " << m_data <<  " ) wasn't setted. "
             << " Ignore the set" <<  std::endl;
        }
 
 
 
    //----------- Implementation of Operators Overloading the class's member -----------//
    const Point& Array::operator [] (int index) const
{   
 
    std::cout << " []  operator for reading was called " ; 
 
    if (index > this->m_size)
    {
        std::cout << "OUT OF BOUND ";
        return this->m_data[0];
    }
    return m_data[index];
}
 
    Point& Array::operator [] (int index)
        {   
 
            std::cout << "[] operator for writing was called \n" ; 
 
            if (index > this->m_size)
            {
                std::cout << "OUT OF BOUND \n" ; 
                return this->m_data[0];
            }
            return m_data[index];
 
 
 
        }
 
 
    Array& Array::operator = (const Array& source)
        {
            
 
            std::cout << " In the Array Assignment operator\n";
 
            if (this == &source)
                {
                std::cout << "Same Array \n"; 
                return *this;
                }
 
            delete [] m_data;
            std::cout << "Deleted m_data array\n";
 
            m_size = source.m_size;                             // shallow copy - this is not dynamic alloc
 
            if (source.m_data)                                  // if not zeros then there is a ref.
            {
                std::cout <<"im here\n"; 
 
                m_data = new Point[source.m_size];              // create a new pointee.
 
                for (int i = 0; i < source.m_size; i++)
                    m_data[i]    =    source.m_data[i];         //copy the points from/to array
            }
            else
                m_data = 0;  //NULL
 
            return *this;
        }
 
    
 
 
    //----------- Implementation of GLOBAL(friend) Ostream << Operator  -----------//
std::ostream& operator << (std::ostream& os, const Array& ObjArray)
{
    os << "\nArray Size = " << ObjArray.m_size << std::endl;
 
        for (int i = 0; i < ObjArray.m_size; i++)
            os << "Array [" << i << "]= "<< ObjArray.m_data[i] << "\n";
 
    return os;
}
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
#include "Point.hpp"
 
            //----------- Implementation of Constructors -----------//
 
    Point::Point() : x(0) , y(0)                                                        // Default constructor (implemented using colon syntax )
        { 
        //  std::cout << "hi my default constructor\n\n\t";
        }                           
 
    Point::Point(double newX , double newY) : x(newX)  , y(newY)                        // Constructor 
        { 
            //std::cout << "hi my constructor\n\n\t"; 
        }               
 
    Point::Point(double value /*, double newY*/) : x(value)  /*, y(newY)    */          // Second Constructor 
        { 
        //std::cout << "hi my constructor\n\n\t"; 
        }   
 
    Point::~Point()                                                                     // Destructor
        {
            //std::cout << "bye my point..\n";
        }                                    
 
    Point::Point (const Point& ObjectOfClassPoint)                                      // Copy constructor
        {
            
            x = ObjectOfClassPoint.x;
            y = ObjectOfClassPoint.y;
        }
        
            //----------- Implementation of Accessor(s) member functions -----------//
 
    std::string Point::ToString() const
        {
            
            std::ostringstream os;                                // std::stringstream object
            os << " Point (" << x << ", " << y << ")";            // customization of output 
            return os.str();                                      
        }
 
    //----------- Implementation of GLOBAL Ostream << Operator  -----------//
 
    std::ostream& operator << (std::ostream& out, Point const& ObjPoint)
{
  
 
    return out << "[" << ObjPoint.x << "," << ObjPoint.y << "]" ; 
    
}
 
        std::ostream& operator << (std::ostream& out, Point const *objPoint)
{
  
    return out << "[" << objPoint->x << "," << objPoint->y << "]" ; 
    
}
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
//main.cpp
 
#include <iostream>
#include "Point.hpp"
#include "Array.hpp"
 
 
 
int main()
 
    {
 
    int i = 0;                                              
    int size_of_array = 5;                                      
    Point** MyArrayOfPointers;
    MyArrayOfPointers = new Point*[size_of_array];                      //Creating an array of Point pointers with 3 elements on the heap.
    
    int some_data_for_x[5] = {1830 , 1901 , 1914, 1900 , 1895} ; 
    int some_data_for_y[5] = {1903 , 1947 , 1211, 1969 , 1789} ; 
 
   
    for (i = 0 ; i <size_of_array; i++ )                                // Create for each element in the array a point on the heap.
        {
            MyArrayOfPointers[i] = new Point(some_data_for_x[i],                
                                                some_data_for_y[i]);                                                                                        
        }
   
    std::cout << "\n\t Setting elements of MemoryManagerArray \n";
 
    Array* MemoryManagerArray = new Array(size_of_array); 
    MemoryManagerArray->SetElement(*MyArrayOfPointers[0],0);                // Setting elements of MemoryManagerArray
    MemoryManagerArray->SetElement(*MyArrayOfPointers[1],1);
    MemoryManagerArray->SetElement(*MyArrayOfPointers[2],2);
    MemoryManagerArray->SetElement(*MyArrayOfPointers[3],3);
    MemoryManagerArray->SetElement(*MyArrayOfPointers[4],17);               // The set will be ignored, because out of bounds
  
    std::cout << "\n\t ---TEST OF [] operator--- \n";
 
    Array* SquareBracktsTESTArray = new Array(size_of_array);
    SquareBracktsTESTArray->SetElement(*MyArrayOfPointers[0],0);                        // Setting elements to Array 
    SquareBracktsTESTArray->SetElement(*MyArrayOfPointers[1],1);
    SquareBracktsTESTArray->SetElement(*MyArrayOfPointers[2],2);
    SquareBracktsTESTArray->SetElement(*MyArrayOfPointers[3],3);
    SquareBracktsTESTArray->SetElement(*MyArrayOfPointers[4],4);
 
    std::cout << "\nSquareBracktsTESTArray [] operator TEST\nReading a element from a given place : \n\n" 
              << (*SquareBracktsTESTArray)[0] << "\n"
              << (*SquareBracktsTESTArray)[1] << "\n"
              << (*SquareBracktsTESTArray)[2] << "\n"
              << (*SquareBracktsTESTArray)[3] << "\n"
              << (*SquareBracktsTESTArray)[4] << "\n"
              << std::endl;
 
    std::cout << "\nSquareBracktsTESTArray [] operator TEST.\nWriting a element to a given place : \n\n" ;
 
    std::cout << "Now [] operator we write [4] and [3] element from place [0] : " ; 
 
    (*SquareBracktsTESTArray)[4] = *MyArrayOfPointers[0]; 
    (*SquareBracktsTESTArray)[3] = *MyArrayOfPointers[0]; 
    
              std::cout << "\n Read again using [] operator:  \n" ;
                 (*SquareBracktsTESTArray)[0].ToString(); 
              std::cout << (*SquareBracktsTESTArray)[1] << "\n"
              << (*SquareBracktsTESTArray)[2] << "\n"
              << (*SquareBracktsTESTArray)[3] << "\n"
              << (*SquareBracktsTESTArray)[4] ; 
 
 
    
    
    std::cout << std::endl; 
    return 0;
 
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.07.2012, 10:31     Overloading [] operators
Посмотрите здесь:

Overloading+Overriding Java
Проблемы с типизацией: Unresolved overloading Haskell
Полиморфизм и overloading Java
Java SE Как посчитать max/ min используя только relational operators?
function overloading C++

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.07.2012, 12:13     Overloading [] operators #2
У вас этот код работает?
Schizorb
 Аватар для Schizorb
508 / 460 / 16
Регистрация: 07.04.2012
Сообщений: 865
Записей в блоге: 1
Завершенные тесты: 1
28.07.2012, 12:22     Overloading [] operators #3
Посмотри эту тему, по-моему похожая проблема:

Перегрузка оператора []
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.07.2012, 12:30     Overloading [] operators #4
В 10 строке Array.cpp нужно так:
C++
1
Array::Array(const int new_size) :m_size(new_size), m_data(new Point[new_size])
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
28.07.2012, 12:31     Overloading [] operators #5
Потому что const версия будет вызываться только для const объектов. Если есть две перегрузки элемент-функции ( const и не const ), то компилятор выбирает нужную по спецификатору const созданного объекта. Если объект не-const, то и функция вызывается не-const. Если же есть только одна версия функции ( const или не-const ), то для константных объектов нельзя вызывать не константные элемент-функции, в то же время для не константных объектов может вызываться константная элемент-функция.
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
28.07.2012, 12:53  [ТС]     Overloading [] operators #6
Цитата Сообщение от alsav22 Посмотреть сообщение
У вас этот код работает?
у меня да. У тебя не работает ?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.07.2012, 12:55     Overloading [] operators #7
Цитата Сообщение от Leeto Посмотреть сообщение
у меня да. У тебя не работает ?
Если исправить, как я написал, то работает, а без этого виснет в конструкторе Array.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
28.07.2012, 13:01     Overloading [] operators #8
alsav22, это происходит, потому что в определении класса, size объявлена после указателя. Данные инициализируются именно в том порядке, в котором они объявлены в определении класса, а не в том, в котором указаны в списке инициализаторов конструктора. Видать компилятор автора сам как то решил проблему, или просто дело случая - в переменной size до инициализации находилось положительное число.
Можно было просто переместить объявление size выше указателя в определении класса.
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
28.07.2012, 13:03  [ТС]     Overloading [] operators #9
Цитата Сообщение от Toshkarik Посмотреть сообщение
Потому что const версия будет вызываться только для const объектов. Если есть две перегрузки элемент-функции ( const и не const ), то компилятор выбирает нужную по спецификатору const созданного объекта. Если объект не-const, то и функция вызывается не-const. Если же есть только одна версия функции ( const или не-const ), то для константных объектов нельзя вызывать не константные элемент-функции, в то же время для не константных объектов может вызываться константная элемент-функция.
Круто !!! спасибо большое !
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.07.2012, 13:33     Overloading [] operators #10
Цитата Сообщение от Toshkarik Посмотреть сообщение
alsav22, это происходит, потому что в определении класса, size объявлена после указателя. Данные инициализируются именно в том порядке, в котором они объявлены в определении класса, а не в том, в котором указаны в списке инициализаторов конструктора. Видать компилятор автора сам как то решил проблему, или просто дело случая - в переменной size до инициализации находилось положительное число.
Можно было просто переместить объявление size выше указателя в определении класса.
Я тоже об этом подумал. Сейчас на другом компиляторе проверю.

Добавлено через 5 минут
Leeto, в array.hpp уберите лишние квалификаторы у конструкторов (19, 20). MSVC это пропускает, а mingv - нет.

Добавлено через 17 минут
Цитата Сообщение от Toshkarik Посмотреть сообщение
alsav22, это происходит, потому что в определении класса, size объявлена после указателя. Данные инициализируются именно в том порядке, в котором они объявлены в определении класса, а не в том, в котором указаны в списке инициализаторов конструктора. Видать компилятор автора сам как то решил проблему, или просто дело случая - в переменной size до инициализации находилось положительное число.
Можно было просто переместить объявление size выше указателя в определении класса.
Mingv только предупреждения выдаёт и сам порядок инициализации правильный делает.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
28.07.2012, 13:54     Overloading [] operators #11
alsav22, нет, ничего он не правит, просто везет, что число положительное. Можете проверить данным кодом:
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
class test {
 public:
   test() {
      count++;
   }
   ~test() {
      count--;
   }
   
   static int count;
};
 
int test::count = 0;
 
class some {
 public:
   some( int newSize )
      : size( newSize ),
        ptr( new test [ size ]) 
   {
      
   }
   
 private:
   test *ptr;
   int size;
};
 
int main () {
   some obj( 10 ); //число объектов, которое мы хотим создать
   
   std::cout << test::count << std::endl; //реальное число объектов, которое создалось ( если вообще создалось )
 
   return 0;
}
Тут не то что везет, принимаемый параметр операцией new - size_t, то есть беззнаковое целое. То есть, если даже int будет отрицательным, при приведении типа к size_t само собой значение становится положительным.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
29.07.2012, 02:00     Overloading [] operators #12
Я так сделал. Добавил в Array ещё одну переменную (поставил первой в объявлении). В конструкторе, в списке инициализаторов, присвоил ей значение m_size и ввывел её значение на консоль. MSVC показал -842150451, mingv 0. Если, как вы пишите, происходит приведение к size_t, то тут ошибку (в MSVC) во время выполнения, выдаёт new, наверное, из-за слишком большого размера массива. Если напсисать: new Point[(size_t)(-842150451)], то компилятор сразу показывает ошибку. В mingv создаётся нулевой массив. Это и по выводу на консоль (если сделано в конструкторах Point) видно.

Добавлено через 16 минут
Попробовал так:
C++
1
std::cout << (size_t)(-842150451)<<std::endl;
В mingv: 18446744072867401165
В MSVC: 3452816845
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
29.07.2012, 02:37     Overloading [] operators #13
У меня, при запуске выше приведенного мной кода, выводить когда чуть больше 2 млрд., когда чуть меньше, и это вместо ожидаемых всего лишь 10. Причем в Debug профиле. На liveworkspace вообще исключение bad alloc. Так что это ошибка, и сомневаюсь что компиляторы что то будут сами исправлять.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
29.07.2012, 02:43     Overloading [] operators #14
Цитата Сообщение от Toshkarik Посмотреть сообщение
это ошибка, и сомневаюсь что компиляторы что то будут сами исправлять.
Я не спорю об этом. Согласен, что mingv ничего не исправляет. Я уже о другом. Почему mingv, при выделении памяти под Array, заполняет её 0 (или не заполняет?), а MVSC этого не делает, и там мусор?
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
29.07.2012, 03:03     Overloading [] operators #15
С этим уже к разработчикам компилятора. С какими параметрами компилируете?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
29.07.2012, 03:10     Overloading [] operators #16
"...при выделении динамической памяти..."

Добавлено через 3 минуты
Цитата Сообщение от Toshkarik Посмотреть сообщение
С какими параметрами компилируете?
Понятия не имею. По умолчанию. Сейчас посмотрел, в настройках компилятора ни один флаг не установлен.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
29.07.2012, 03:16     Overloading [] operators #17
Если в debug режиме, то вполне возможно, и это нормально.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
29.07.2012, 03:40     Overloading [] operators #18
Если в mingv просто создать объект Array:
C++
1
Array p1(3);
, то происходит бесконечный цикл с вызовом конструктора по умолчанию Point().

Добавлено через 2 минуты
Цитата Сообщение от Toshkarik Посмотреть сообщение
Если в debug режиме, то вполне возможно, и это нормально
В release то же самое.

Добавлено через 18 минут

Не по теме:

Вывод. Так делать нельзя. И на этом можно остановиться.

Yandex
Объявления
29.07.2012, 03:40     Overloading [] operators
Ответ Создать тему
Опции темы

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