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

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
#1

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

05.08.2012, 22:29. Просмотров 1461. Ответов 5
Метки нет (Все метки)

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++
Нужно вывести на экран порядковый номер объекта, используя статическую переменную для подсчета общего количества объектов #include...

Статическая переменная в методе класса - C++
Локальные статические переменные сохраняют свое значение между вызовами функций. Если сделать тоже самое с методом класса, то этот статик...

Статическая переменная возвращает непонятные шестизначные числа - C++
Здравствуйте, обитатели этого форума. Кому не лень помогите разобраться со статической переменной number_of_left_seats. Почему она не...

Почему компилируется не объявленная переменная в шаблоне? - C++
Нашел на просторах интернета такой код template&lt;typename T&gt; T foo(int x, T ololo) { a = 5; } int main() {

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Nick Alte
Эксперт С++
1636 / 1008 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 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
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
05.08.2012, 22:50  [ТС] #3
Цитата Сообщение от Nick Alte Посмотреть сообщение
Шаблон класса не является самостоятельным типом. Выносить реализацию методов шаблона в отдельный .cpp нельзя, в функции main должен быть доступен текст реализации функций. Следовательно, содержимое array.cpp должно перекочевать в array.hpp. Это раз. [/CPP]

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

Глобальная переменная определена в хидере. Компилятор ругается на то, что переменная переопределена несколько раз - C++
Исходники: /* main.cpp */ #include &quot;hider.h&quot; int main(void) { return 0; } /* foo.cpp */

Переменная или переменная и условие - C++
Привет всем. Стало интересно. Есть предположим функция. В ней ссылкой передается аргумент Status; Как лучше сделать? ...

Статическая линковка - C++
Добрый вечер. Прочитал что бы екзешка запускалась на любом компьютере нужно сделать статическую линковку. То есть прикрепить к екзешнику...

Статическая библиотека - C++
lib main.h namespace x { int __stdcall WindowCreate( ... ); } main.cpp


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
06.08.2012, 00:07
Ответ Создать тему
Опции темы

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