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

Статическая переменная в шаблоне - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
05.08.2012, 22:29     Статическая переменная в шаблоне #1
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
45
46
47
48
49
50
51
52
//                                                      
//                                                  (---.Array_hpp---)
//
#ifndef Array_HPP   // Preprocessor gates
#define Array_HPP
 
    #include <sstream>
    #include <iostream>
    #include <exception>
 
    template <class Type>   //Remove the "=double" default parameter.
    class Array
        {
    
            private:                // Declaration of private data members 
              unsigned int m_size;
              Type*        m_data;          //m_data should be a pointer, since you want to allocate data to it
 
            public:                 // Public declaration of data members (in given example haven't ) and member functions 
              static
                  int m_size_default;
                //----------- Declaration of Constructors -----------//
              Array();                                  // Default constructor
              Array(const unsigned int new_size);       // Constructor 
              Array(const Array<Type>& ObjArray);       // Copy constructor
              ~Array();                                 // Destructor
 
              //----------- Declaration of  Accessors member functions -----------//
              Type& GetElement(const unsigned int index) const;
 
              static int DefaultSize() ;
              static void DefaultSize( int newSize) ;
 
                          //----------- Declaration of Modificator(s) member functions -----------//
              void SetElement(const Type& ObjType, const unsigned int index);
              void Swap(Array& ObjArray);  
 
              //----------- Declaration of Operators Overloading the class's members -----------//
              Array<Type>& operator =   (const Array& ObjArray);                //Const correctness here.
              const Type& operator  []  (unsigned int index) const;
              Type& operator        []  (unsigned int index);           
        };
///*
    #ifndef Array_cpp // Must be the same name as in source file #define
 
        #include "Array.cpp"
 
    #endif //#ifndef Array_cpp is CLOSED
//*/
 
//  #include "Array.inl"
#endif //  #ifndef Array_HPP is CLOSED


Array_CPP
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
//                                                      
//                                                  (---.Array_CPP---)
//  
 
    #ifndef Array_CPP   // Preprocessor gates
    #define Array_CPP
 
        #include "Array.hpp"
                                    
    template <class Type>
    int Array<Type>::m_size_default = 10;
                    //----------- Implementation of Constructors -----------//
        template <class Type>
        Array<Type>::Array() : m_size(10), m_data(0)
            { 
 
            }
 
        template <class Type>
        Array<Type>::Array(unsigned int new_size) 
            : m_size(new_size), m_data(new Type[new_size])
            { 
 
            }
 
        template <class Type>
        Array<Type>::Array(const Array& ObjArray) : m_data(0), m_size(0)
            {
              if(!ar.m_data) {return;}
 
              Array tmp; //Copy construct into another temporary array, this way, if something throws, tmp will clean itself up.
 
              //Create the array
              tmp.m_data = new Type[ar.m_size];
              tmp.m_size = ar.m_size;
 
              //Copy the array elements
              for(unsigned int i = 0; i < tmp.m_size; ++i)
                {tmp.m_data[i] = ar.m_data[i];}
 
              //All done! swap into this!
              this->Swap(tmp);
            }
 
 
        template <class Type>
        Array<Type>::~Array()
            {
              //Technically, the if is not necessary
              if(m_data)
              {
                delete[] m_data;
                m_data = 0;
              }
 
              //Not necessary either, but just to be clean
              m_size = 0;
            }
 
        //----------- Implementation of Accessor(s) member functions -----------//
 
        template <class Type> 
        Type& Array<Type>::GetElement(const unsigned int index) const
            {
                std::cout 
                << "GetElement -> " ;
    
                    if (index >= m_size || index < 0)
                        { 
                            throw std::out_of_range 
                                ("Out of range error in void Array<Type>::GetElement");
                        } 
 
                return m_data[index];
            }
 
        
        //----------- Implementaion of Modificator(s) member(s) function -----------//
 
        template <class Type>
        void Array<Type>::Swap(Array& ObjArray)
            {
                //std::swap()  - try to implement std swap function 
              Type* data = m_data;
       unsigned int size = m_size;
              m_data     = ObjArray.m_data;
              m_size     = ObjArray.m_size;
         ObjArray.m_data = data;
         ObjArray.m_size = size;
            }
 
        template <class Type> 
        void Array<Type>::SetElement(const Type& ObjType,unsigned int index)
            {
 
                    if (index >= m_size || index < 0 )
                        { 
                            throw std:: out_of_range ("out of range error in void Array<Type>::SetElement");
                        }
                    m_data[index] = ObjType;
            //  std::cout << "Set Element <- " << ObjType  << std::endl;
            }
 
        template <typename Type>
        int Array<Type>::DefaultSize() 
            { 
                return m_size_default;
            }
 
        template <typename Type>
        void Array<Type>::DefaultSize( int newSize) 
            { 
                m_size_default = newSize; 
            }
 
 
        //----------- Implementation of Operators Overloading the class's member -----------//
 
        template <class Type>
        Array<Type>& Array<Type>::operator = (const Array& ObjArray)
            {
              //Check self assign:
              if(this == &ObjArray) {return *this;}
 
              Array<Type> copy(ObjArray);   //Create a copy of ObjArray; If this fails, then *this will not be changed, and nothing will leak
 
                                            //Succeeded creating copy. Now we can put it inside this
              this->Swap(copy);             //And then swap the copy into this!
 
              return *this;
            }
 
        template <class Type> 
        Type& Array<Type>::operator [] (unsigned int index) 
            {
                cout << "Array [] operator" << endl;
 
                if (index >= this->m_size)
                    {
                        cout << "i am hreeeee" << endl;
                        return this->m_data[0];
                    }
                return m_data[index];
            }
 
        template <class Type> 
        const Type& Array<Type>::operator [] (unsigned int index) const
        {   
            if (index > this-> m_size)
                    {
                        std::cout 
                            << "OUT OF BOUND ";
                        return this->m_data[0];
                    }
            return m_data[index];
        }
 
 
// /*
    #endif //Array_CPP
 
//      */


main_cpp
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
//                                                      
//                                                  (---.main_cpp---)
//
        #include "Array.hpp"
        #include <iostream>
        #include <exception>
 
        using namespace std;
 
 
 
int main()
{
    
 
    Array<int> intArray1;
    Array<int> intArray2;
    Array<double> doubleArray;
 
    cout<<intArray1.DefaultSize()<<endl;
    cout<<intArray2.DefaultSize()<<endl;
    cout<<"double array old defaul size " << doubleArray.DefaultSize()<< "\n\n";
 
    intArray1.DefaultSize(15);
   
    cout<<intArray1.DefaultSize()<<endl;
    cout<<intArray2.DefaultSize()<<endl;
    cout<<"\n\n double array new defaul size " << doubleArray.DefaultSize()<< "\n\n";
 
    return 0 ; 
    
}


Допустим есть вот какой вот проект
Соль его в том что у Array класса есть переменная static. И майн доходчиво должно демонстрировать свойства этой static переменной... но только не такому быдло недо кодеру как я... пожалуйста объясните что происходит в main.cpp и как на этом примере работает static
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.08.2012, 22:29     Статическая переменная в шаблоне
Посмотрите здесь:

C++ Статическая локальная переменная
C++ Статическая переменная
Статическая линковка C++
C++ Статическая линковка
Почему компилируется не объявленная переменная в шаблоне? C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
05.08.2012, 22:40     Статическая переменная в шаблоне #2
Шаблон класса не является самостоятельным типом. Выносить реализацию методов шаблона в отдельный .cpp нельзя, в функции main должен быть доступен текст реализации функций. Следовательно, содержимое array.cpp должно перекочевать в array.hpp. Это раз. Статические члены каждого класса должны быть объявлены ещё и отдельно по тем же правилам, что и глобальные переменные. Это два. Поскольку самостоятельным типом является то, что получается из шаблона при подстановке конкретных параметров, в main.cpp надо объявить статические переменные обеих инстанциаций шаблона Array:
C++
1
2
int Array<int>::m_size_default = 0;
int Array<double>::m_size_default = 0;
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
05.08.2012, 22:50  [ТС]     Статическая переменная в шаблоне #3
Цитата Сообщение от Nick Alte Посмотреть сообщение
Шаблон класса не является самостоятельным типом. Выносить реализацию методов шаблона в отдельный .cpp нельзя, в функции main должен быть доступен текст реализации функций. Следовательно, содержимое array.cpp должно перекочевать в array.hpp. Это раз. [/CPP]

Так у меня препроцессор гейты
и все компилируется
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.08.2012, 22:51     Статическая переменная в шаблоне #4
Цитата Сообщение от Nick Alte Посмотреть сообщение
Следовательно, содержимое array.cpp должно перекочевать в array.hpp.
Он в Array.hpp делает #include "Array.cpp"
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
05.08.2012, 23:12     Статическая переменная в шаблоне #5
Эм... модификатор поля static читается как «один на класс» (или как «общий для всех объектов класса»). Единственная тонкость, о которой надо помнить: Array<int> и Array<double> — это два разных класса; соответственно, и static-члены у них у каждого свои собственные. Вот и покажите, что они различаются у двух разных классов, но совпадают у одного и того же.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
06.08.2012, 00:07     Статическая переменная в шаблоне #6
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Вот и покажите, что они различаются у двух разных классов, но совпадают у одного и того же.
Как раз и показал. Изменил значение static-переменной, через метод одного из объектов класса для int, и оно изменилось и у другого объекта этого же класса, а у объекта класса для double, значение static-переменной, осталось без изменений.
Yandex
Объявления
06.08.2012, 00:07     Статическая переменная в шаблоне
Ответ Создать тему
Опции темы

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