So I am quite wary new to C++ and I really do not understand templates and how to use tham thow I rad wikipedia and started reading like 2000 pages long book on C++... So I am probably way 2 impatient but I wonder If using C++ templates we can make for example such simple class pair work with costume structures instead of chars.
#include <iostream>
#include <vector>
// Boost
#include <boost/thread.hpp>
#ifndef _IGraphElementBase_h_
#define _IGraphElementBase_h_
#pragma once
using namespace std ;
class IGraphElementBase {
public:
boost::thread GraphWorker;
mutable boost::mutex GraphItemMutex;
boost::condition_variable GraphItemMutexConditionVariable;
int SleepTime;
// Function for preparing class to work
virtual void Init(){ SetSleepTime(1);}
void SetSleepTime(int timeMS)
{
SleepTime = timeMS;
}
// Function for data update // word virtual makes it possible to overwrite it
virtual void updateData(){}
void StartThread()
{
GraphWorker = boost::thread(&IGraphElementBase::Call, this);
}
virtual void CleanAPI(){}
virtual void Clean()
{
GraphWorker.interrupt();
GraphWorker.join();
CleanAPI();
}
virtual void CastData(){}
//Here is a main class thread function in infinite loop it calls for updateData function
void Call()
{
try
{
for(;;){
boost::this_thread::sleep(boost::posix_time::milliseconds(SleepTime));
boost::mut开发者_C百科ex::scoped_lock lock(GraphItemMutex);
boost::this_thread::interruption_point() ;
updateData();
lock.unlock();
CastData();
GraphItemMutexConditionVariable.notify_one();
}
}
catch (boost::thread_interrupted)
{
// Thread end
}
}
};
#endif // _IGraphElementBase_h_
#include "IGraphElementBase.h"
#ifndef _IGraphElement_h_
#define _IGraphElement_h_
using namespace std ;
class IGraphElement : public IGraphElementBase{
// We should define prototype of functions that will be subscribers to our data
typedef void FuncCharPtr(char*, int) ;
public:
struct GetResultStructure
{
int length;
char* ptr;
};
// initGet sets up a pointer holding a copy of pointer of data we want to return on Get() call
void InitGet(char * pointerToUseInGetOperations, int pointerToUseInGetOperationsSize)
{
pointerToGet = pointerToUseInGetOperations;
pointerToGetSize = pointerToUseInGetOperationsSize;
}
// Function for adding subscribers functions
void Add(FuncCharPtr* f)
{
FuncVec.push_back(f);
}
// Returns pointer to copy of current graphItem processed data
GetResultStructure Get()
{
boost::mutex::scoped_lock lock(GraphItemMutex);
char * dataCopy = new char[pointerToGetSize];
memcpy (dataCopy,pointerToGet,pointerToGetSize);
lock.unlock();
GraphItemMutexConditionVariable.notify_one();
GetResultStructure result;
result.ptr = dataCopy;
result.length = pointerToGetSize;
return result;
}
void Clean()
{
GraphWorker.interrupt();
GraphWorker.join();
CleanAPI();
//delete[] pointerToGet;
//pointerToGet = 0;
}
// Cast data to subscribers and clean up given pointer
void CastData(){
for (size_t i = 0 ; i < FuncVec.size() ; i++){
char * dataCopy = new char[pointerToGetSize];
memcpy (dataCopy,pointerToGet,pointerToGetSize);
FuncVec[i] (dataCopy, pointerToGetSize) ;}
}
// Cast given data to subscribers and clean up given pointer
void CastData(char * data, int length){
for(size_t i = 0 ; i < FuncVec.size(); i++){
char* dataCopy = new char[length];
memcpy(dataCopy, data, length);
FuncVec[i](dataCopy, length);
}
}
private:
// Char pointer to hold a copy of pointer of data we want to return on Get() call
char* pointerToGet;
int pointerToGetSize;
// Vector to hold subscribed functions
vector<FuncCharPtr*> FuncVec ;
};
#endif // _IGraphElement_h_
So what is most intresting for me in that classes in short:
- typedef void FuncCharPtr(char*, int) ;
- vector<FuncCharPtr*> FuncVec ;
- functions like void CastData(char * data, int length)
It is really wary intresting for me if it is possile to somehow using templates make my classes work with costume structures. So Is it possible and how to do such thing?
Templates are a parameterization of a class. That is, instead of having a bunch of different classes such as
class myclass_int
{
int x;
}
class myclass_double
{
double x;
}
etc...
if you can see the pattern, the only thing different is the type used, SO, we will use an abstract type called a template as a sort of place holder,
class myclass_T
{
T x;
}
THIS CLASS IS NOT A SINGLE CLASS BUT A WHOLE COLLECTION. If we replace T with int we get the first class and T with double we get the second.
But when we instantiate myclass_T we must then specify what T actually is(is it in an int, double, etc..)?
so we will define this parameterized class as
template <typename T>
class myclass
{
T x;
}
And use T as it we already new what it really was.
That one class represents all the possible classes you could make up that had specific types used(I gave 2 instances at the start).
Templates simply make it easier to define such classes. There are a lot more to it than that but it is the foundation of why they are useful. The way to think of a templated class is not as a class but as a "Super class". That is, a class that has the ability to take on different representations.
It's not a difficult concept BUT if you don't have a lot of experience with oop you might not really see why they are useful and think they make things more complex. But once you end up having to write very many similar classes that all only differ by the types used then you'll see why they are so useful(they are actually quite powerful because they end up being able to do a lot more).
精彩评论