Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
вот так было бы правильней, используя наследственность, ну... 20.12.07 02:13 Число просмотров: 3271
Автор: + <Mikhail> Статус: Elderman
|
вот так было бы правильней, используя наследственность, ну естественно надо сделать private copy constructor и assignment operator.
Вообче то ето школьная задачка, не так ли?
class ITopic
{
public:
virtual ~ITopic(){};
virtual _bstr_t GetValue() = 0;
};
class CTopicVector
{
private:
//I would use a smart pointer
//example:
//map<int , smart_ptr<ITopic> > m_TopicData
map<int , ITopic*> m_TopicData;
CRITICAL_SECTION m_cs;
public:
CTopicVector()
{
InitializeCriticalSection(&m_cs);
};
virtual ~CTopicVector()
{
ClearVector();
DeleteCriticalSection(&m_cs);
};
void ClearVector()
{
map<int , ITopic*>::iterator it;
EnterCriticalSection(&m_cs);
try
{
for(it = m_TopicData.begin();it != m_TopicData.end();++it)
{
delete (*it).second;
}
m_TopicData.clear();
}catch(...){};
LeaveCriticalSection(&m_cs);
}
int GetSize()
{
return (int)m_TopicData.size();
}
int AddTopic(ITopic* pTopic)
{
int iId = (int)m_TopicData.size();
EnterCriticalSection(&m_cs);
try
{
m_TopicData[iId] = pTopic;
}catch(...){}
LeaveCriticalSection(&m_cs);
return iId;
};
//unsafe reference to an object
ITopic* GetUnsafeTopic(int iId)
{
ITopic *pTopic = NULL;
EnterCriticalSection(&m_cs);
try
{
pTopic = m_TopicData[iId];
}catch(...){}
LeaveCriticalSection(&m_cs);
return pTopic;
}
};
class CTopic1: public ITopic
{
private:
_bstr_t m_bstrVal;
int m_iVal;
public:
CTopic1(_bstr_t bstrVal, int iVal)
:m_bstrVal(bstrVal),m_iVal(iVal){}
_bstr_t GetValue()
{
return m_bstrVal + L":" + _bstr_t(_variant_t(m_iVal)) + L"\n";
}
};
class CTopic2: public ITopic
{
private:
double m_dVal;
bool m_bVal;
public:
CTopic2(double dVal, bool bVal)
:m_dVal(dVal),m_bVal(bVal){}
_bstr_t GetValue()
{
return _bstr_t(_variant_t(m_dVal)) + L":" + (m_bVal?L"true\n":L"false\n");
}
};
int _tmain(int argc, _TCHAR* argv[])
{
CTopicVector TopicVector;
TopicVector.AddTopic(new CTopic1(L"Topic1",1));
TopicVector.AddTopic(new CTopic1(L"Topic1",2));
TopicVector.AddTopic(new CTopic1(L"Topic1",3));
TopicVector.AddTopic(new CTopic2(3.14,true));
int size = TopicVector.GetSize();
for(int i = 0; i < size; ++i)
{
ITopic* pTopic = TopicVector.GetUnsafeTopic(i);
if(pTopic)
{
OutputDebugString(pTopic->GetValue());
}
}
return 0;
}
---
> Буду рад и благодарен, если кто-нить подскажет элегантное > решение. Задача такова: > Есть произвольные структуры данных (векторы, массивы и т.д) > classA {...} > classBB {...} > .... > > и есть векторы, массивы, мапы этих структур > > vector<A> va; > vector<BB> vb; > ... > > Каждый экземпляр таких структур/классов может > быть”отображён” на более простой тип, например, строку, > целое, булево и т.д. Т.е. Для каждого класса может быть > определена некоторая функция, типа virtual variant_t > GetTopicValue(const LPVOID pdata) const. > > > Существует поток, в котором надо единообразно периодически > “пробегать” по списку (контейнеру ссылок) всех этих > элементов, с тем чтобы в цикле получать разультат > “отображения” каждого экемпляра списка, например, в > псевдокоде надо выполнить: > > loop for each in (va,vb, ...) > v = each.GetTopicValue(NULL); > > Другие потоки добавляют в данный список ссылки на > существующие структуры, например, когда данные обновлены. > > Я смотрел аналогичный код некоторых гурей, у которых я > учусь– мне плохо стало от крутизны, непонятности, > темплейтности, объектно ориентированности и ненужности. > Попробовал сделать сам – получается просто, но хочется ещё > более просто, изящно и элегантно. Попробовал темлейты > прикрутить (как у гурей) – не получается чтоб это нужно > было (от недостатка моих знаний, видимо). Наколеночный код > у меня таков: > > #include "stdafx.h" > #include <string> > #include <vector> > #include <sstream> > #include "comdef.h" > > > /////////////////////////////////////////////////////////// > ////// > // > // Generic topic containers > // > /////////////////////////////////////////////////////////// > ////// > > interface ITopic { > virtual variant_t GetTopicValue(const LPVOID pdata) > const PURE; > virtual ~ITopic(){}; > }; > > class Topic { > public: > virtual variant_t GetTopicValue(const LPVOID pdata) > const > { > return (m_topicInterface ? > m_topicInterface->GetTopicValue(pdata) : variant_t()); > } > Topic() : m_topicID(0L), m_topicInterface(NULL) {} > long m_topicID; > ITopic* m_topicInterface; > }; > > class TopicVector > { > public: > void AddTopic(const long ID, ITopic* item) > { > Topic topic; > topic.m_topicID = ID; > topic.m_topicInterface = item; > m_vector.push_back(topic); > } > size_t Size(void) const > { > return m_vector.size(); > } > Topic& operator[](const size_t idx) > { > return m_vector.at(idx); > } > void Lock(void) > { > ::EnterCriticalSection(&m_cs); > } > void Unlock(void) > { > ::LeaveCriticalSection(&m_cs); > } > TopicVector() > { > ::InitializeCriticalSection(&m_cs); > } > ~TopicVector() > { > Lock(); > for (size_t i = 0; i < m_vector.size(); > i ++) > delete > m_vector.at(i).m_topicInterface; > Unlock(); > ::DeleteCriticalSection(&m_cs); > } > private: > std::vector<Topic> m_vector; > CRITICAL_SECTION m_cs; > }; > > /////////////////////////////////////////////////////////// > ////// > // > // Example: concrete topics > // > /////////////////////////////////////////////////////////// > ////// > > class ConcreteTopicA: public ITopic { > public: > virtual variant_t GetTopicValue(const LPVOID data) > const > { > std::ostringstream s; > s << m_sval << ":" << > m_ival; > return _bstr_t(s.str().c_str()); > } > ConcreteTopicA(const std::string& sval, const > int ival): m_sval(sval), m_ival(ival) {}; > virtual ~ConcreteTopicA() {}; > private: > std::string m_sval; > int m_ival; > }; > > class ConcreteTopicB: public ITopic { > public: > virtual variant_t GetTopicValue(const LPVOID data) > const > { > std::ostringstream s; > s << m_bval << ":" << > m_fval; > return _bstr_t(s.str().c_str()); > } > ConcreteTopicB(const bool bval, const double& > fval): m_bval(bval), m_fval(fval) {}; > virtual ~ConcreteTopicB() {}; > private: > bool m_bval; > double m_fval; > }; > > > int _tmain(int argc, _TCHAR* argv[]) > { > // create concrete topics > ConcreteTopicA* topicA = new ConcreteTopicA("some > string value", 100); > ConcreteTopicB* topicB = new ConcreteTopicB(true, > 1000.0); > > // add topics > TopicVector topics; > topics.Lock(); > > topics.AddTopic(1, topicA); > topics.AddTopic(2, topicB); > > //print it > variant_t v; > for (size_t i = 0; i < topics.Size(); i ++) { > v = topics[i].GetTopicValue(NULL); > // TO DO > } > > topics.Unlock(); > > return 0; > } > > Спасибо, если кто предложит красивое, простое решение.
|
|
|