c++ - 初学者和 C++ 模板 : Is it an how possible using C++ template make a class oriented to work with chars work with costume structures?

标签 c++ oop templates class boost

所以我对 C++ 非常谨慎,我真的不了解模板以及如何使用它们,我浏览了维基百科并开始阅读大约 2000 页的 C++ 长书...所以我可能有点不耐烦,但我想知道如果使用 C++ 模板,我们可以使这种简单的类对使用服装结构而不是字符。

#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::mutex::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_

简而言之,那门课对我来说最有趣的是什么:

-   typedef void FuncCharPtr(char*, int) ;
-   vector<FuncCharPtr*> FuncVec ;
-   functions like void CastData(char * data, int length)

如果有可能以某种方式使用模板使我的类(class)与服装结构一起工作,这对我来说真的很有趣。那么是否有可能以及如何做这样的事情?

最佳答案

模板是类的参数化。也就是说,而不是有一堆不同的类,例如

class myclass_int
{
   int x;
}

class myclass_double
{
   double x;
}

等...

如果你能看到模式,唯一不同的是使用的类型,所以,我们将使用称为模板的抽象类型作为一种占位符,

class myclass_T
{
    T x;
}

这个类不是一个单独的类,而是一个完整的集合。如果我们用 int 替换 T,我们得到第一个类,用 double 替换 T,我们得到第二个。

但是当我们实例化 myclass_T 时,我们必须指定 T 实际上是什么(它是 int、double 等)吗?

所以我们将这个参数化类定义为

template <typename T>
class myclass
{
   T x;
}

并使用 T,因为我们已经了解了它的实际情况。

该类代表您可以组成的所有可能使用特定类型的类(我在开始时给出了 2 个实例)。

模板只是让定义此类类变得更容易。它的意义远不止于此,但这是它们有用的基础。将模板类视为“父类(super class)”而不是类的方式。也就是说,一个类能够采用不同的表示形式。

这不是一个困难的概念,但是如果您没有太多的 oop 经验,您可能不会真正明白它们为什么有用,并认为它们使事情变得更复杂。但是,一旦您最终不得不编写许多相似的类,而这些类仅在所使用的类型上有所不同,那么您就会明白为什么它们如此有用(它们实际上非常强大,因为它们最终能够做更多的事情)。

关于c++ - 初学者和 C++ 模板 : Is it an how possible using C++ template make a class oriented to work with chars work with costume structures?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4772203/

相关文章:

c++ - 如何将 malloc 返回的指针视为多维数组?

algorithm - 多级遍历的数据结构

python - 类和函数范围

c++ - 如何在ChaiScript 中注册重载的模板成员函数?

c++ - 这个关于类模板中静态的编译器错误是什么意思?

c++ - 如何在映射中存储缓冲区的值而不是其引用?

c++ - std::unordered map with custom key 在 ~ 31,000 个元素处失败

c++ - 具有默认模板参数的参数包

oop - 形容词的接口(interface)命名

c++ - 从模板类继承和调用模板函数时出错