В общем идея - нужен шаблон класса потокобезопасной переменной.
По идее - выглядеть должен вот так:
template <typename T> class SafetyValue { protected: T fValue; CRITICAL_SECTION fLock; inline void lock() { EnterCriticalSection( &fLock); } inline void unlock( ) { LeaveCriticalSection( &fLock); } public: SafetyValue( T initValue) { InitializeCriticalSection( &fLock); fValue = initValue; } ~SafetyValue( ) { DeleteCriticalSection( &fLock); } void setValue( T value) { lock( ); __try { fValue = value; } __finally { unlock( ); } } T getValue( ) { T temp; lock( ); __try { temp = fValue; } __finally { unlock( ); } return temp; } void getValue( T* value) { lock( ); __try { ( *value) = fValue; } __finally { unlock( ); } } };
И теперь делаем класс SafetyUInt:
class SafetyUInt : public SafetyValue<unsigned int> { protected: public: unsigned int genValue() { lock( ); __try { return ++fValue; } __finally { unlock( ); } } };
Объявляем:
SafetyUInt IdGen(0);
Компилятор нам в ответ:
error C2664: SafetyUInt::SafetyUInt: невозможно преобразовать параметр 1 из 'int' в 'const SafetyUInt &'
Где я туплю, или, может, я много хочу?
x
У шаблона SafetyValue прописан конструктор - вот тут кроется как раз засада - может быть данный конструктор просто отваливается. ХЗ - объясните пож.
NIXIUS
а почему ты не хочешь написать конструктор для SafetyUInt? В текущем виде компилятор генерит два конструктора - по умолчанию (без параметров) и копирования (с одним параметром угадай какого типа). Твою запись SafetyUInt IdGen(0); компилятор пытается интерпретировать именно как конструктор копирования, но типы не совпадают же. Вот и.
NIXIUS
Где я туплю, или, может, я много хочу?
в SafetyUInt добавить:
public: SafetyUInt(unsigned int a) : SafetyValue<unsigned int>( a) { }
>ХЗ - объясните пож.
компилер "пробрасывает" только конструкторы по умолчанию
FireFenix
Спасибо! Не кодил на сипипи давно, в памяти есть что-то про нюанс с конструкторами в шаблонах - спасибо, что освежили.
NIXIUS
У вас два варианта:
1. Вручную пробросить все конструкторы от наследника к предку
2. Переложить эту задачу на компилятор:
//Title of this code #include <iostream> using namespace std; template<class T> struct base { base(const T& v) { cout<<"start value = "<<v<<endl; } }; struct der: base<int> { using base::base; }; int main( ) { std::cout << "Hello, world!\n"; der test( 1); }
Тема в архиве.