Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Статические атрибуты в шаблоне


Автор: gray_k 21.5.2004, 13:38
Я пытаюсь создать шаблон класса со статическим элементом:
Код
template <class T> class Proba
{
private:
 static int var;
public:
 static int get();
};

template <class T> int Proba<T>::get()
{
 ShowMessage(IntToStr(var));
}

Затем в другом модуле я пишу:
Код
typedef Proba<int> MyType;
class a : public MyType
{

};
//здесь компилятор выдаёт ошибку "Var is not a member of 'a'"
int a::var = 0;

Никто не сталкивался с подобным?

Автор: bel_nikita 21.5.2004, 13:50
А так не пробывал:
Цитата
template<> int a<int>::var = 0;

Автор: gray_k 21.5.2004, 14:04
Пробовал, пробовал.
Тут дело в том, что статические элементы в С++ не наследуются. У меня здесь вопрос как бы реализовать код так, чтобы можно было для разных классов использовать некоторые одинаковые методы работы со статическими элементами.

Автор: bel_nikita 21.5.2004, 14:21
То gray_k: так может применить виртуальное наследование. Если хочешь, чтоб базовый класс (объект) был для всех один

Автор: bel_nikita 21.5.2004, 14:32
Че та я не понял??? wow.gif
Код
// *.H
template <class T> class Proba
{
private:
static int var;
public:
static int get();
};

template <class T> int Proba<T>::get()
{
return var;
}

typedef Proba<int> MyType;
class aaaaa : public MyType
{
};

Код
// *.cpp
int aaaaa::var = 0;

Все компилится!

Автор: gray_k 21.5.2004, 14:37
Нет немного не то. У меня есть несколько классов. У них элементы и функции - статические. Причем элементы различаются только типом, а так их набор одинаков. И для всех классов есть несколько типовых статических функция, которые меняют эти переменные. Естественно возникла идея, реализовать это в шаблоне. Собственно я сделал уже. Вот реализация:
шаблон:
Код
template <class T> class Proba
{
private:
 static int var;
public:
 static void set(int val);
 static void get();
};
template <class T> void Proba<T>::get()
{
 ShowMessage(IntToStr(var));
}
template <class T> void Proba<T>::set(int val)
{
 var = val;
}
template <class T> int Proba<T>::var=random(100);


дочерние классы:
Код

class a : public Proba<int>
{};
class b:public Proba<char>
{};


обращение к элементам:
Код

void __fastcall TForm4::Button1Click(TObject *Sender)
{
 a::get();
 a::set(10);
}
//---------------------------------------------------------------------------

void __fastcall TForm4::Button2Click(TObject *Sender)
{
 b::get();
 b::set(20);
}
//---------------------------------------------------------------------------

Добавлено @ 14:40
Цитата
Все компилится!

А у меня такой код не скомпилился smile.gif. Посмотри я выше привильную реализацию написал.
У тебя компилятор какой? У меня Builder C++6.

Автор: bel_nikita 21.5.2004, 14:52
Че-та я не понял. В чем проблема?
Не понимаю зачем делать шаблон, если все переменныые int
Вот код, все работает:
Код
template <class T> class Proba
{
 typedef T TypeData;
private:
static TypeData var;
public:
static void set(T val);
static TypeData get();
};

template <class T> T  Proba<T>::get() { return var; }

template <class T> void Proba<T>::set(T val) { var = val; }

template <class T> T Proba<T>::var=100;

class Test1 : public Proba<int>
{};
class Test2 : public Proba<char>

Код
 Test1 asd; // первый
 Test1 asd1; // второй

 printf("\nasd.get()=%d",asd.get()); //100
 
 asd.set(200);
 printf("\nasd.get()=%d",asd.get());//200

 asd1.set(500);
 printf("\nasd1.get()=%d",asd.get());// 300

Добавлено @ 14:53
Компилер: MSVC6

Автор: gray_k 21.5.2004, 15:00
Цитата
Не понимаю зачем делать шаблон, если все переменныые int

Это просто тестовый пример. Настоящая реализация другая.

Автор: bel_nikita 21.5.2004, 15:12
gray_k
А работает?
У меня все ОК

Автор: gray_k 21.5.2004, 15:24
Код во втором ответе работаетsmile.gif. Я же написал, что это правильная реализация smile.gif.
А то что я написал в вопросе не компилится, и про который ты сказал, что у тебя скомпилился. Ни на Борладе, ни на VC.NET.

Автор: Sined 21.5.2004, 16:14
gray_k, вот что у меня чработало в 6 билдере. Может быть... ошибка где-то рядом.

Код

template<class T>
class Proba
{
public:
Proba(){};
~Proba(){};
static T ch;
static T& get_ch(){return ch};
T cd;
};

class B:public Proba<int>
{
B(){};
~B(){};
static int get_c(){return get_ch();};
};


Работает даже так.

Код

template<class T>
class Proba
{
public:
Proba(){};
~Proba(){};
static T ch;
static T& get_ch(){return ch;};
T cd;
};

class B: public Proba<int>,public Proba<char>
{
public:
B(){};
~B(){};
static int get_c(){return Proba<int>::get_ch();};
};
int Proba<int>::ch=15;

Ну я и идиот!!!! Слава Богу, пока репутации нет, а то сейчас получил бы по шапке. Пример, рабочий, однако в его интерпретации я сильно ошибся.
Правильно, видимо,так
1) При наследовании от шаблонного класса ты создаешь по сути дела 2 класса
свой+шаблонный. За этим шаблонным(например, Proba<int>)ты закрепляешь 1 статический тип данных, потом все классы типа Proba<int> будут этим членом данных пользоваться.
2) Теперь представь, что у тебя есть 2 класса наследующих от Proba<int> и в одном ты стат.член изменил, а вдругом он по идее изменится не может, НО
по сути дела у тебя есть 4 класса 2 наследника(А,B) и 2 экземпляра Proba<int>, причем с неравными стат. членами, что просто противоречит определению стат.члена=> единственный возможный способ описан выше.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)