开发者

Beginner and C++ templates: Is it an how possible using C++ template make a class oriented to work with chars work with costume structures?

开发者 https://www.devze.com 2023-02-06 00:35 出处:网络
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

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).

0

精彩评论

暂无评论...
验证码 换一张
取 消