Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何转换;“正常”;C++;类到模板?_C++_Class_Templates - Fatal编程技术网

C++ 如何转换;“正常”;C++;类到模板?

C++ 如何转换;“正常”;C++;类到模板?,c++,class,templates,C++,Class,Templates,我试图将一个类从“普通”类转换为模板类,但我不理解正确的语法。下面是一个(大大简化的)示例,我从中开始。这是VisualStudio 2010,C++,针对X64架构,Windows 7。 目标是将类T重写为模板,以处理TEntry或新类OtherTEntry,其概念类似于TEntry,具有相同的成员函数,但具有不同的数据成员 我很感激你给我的建议。如果可能的话,我希望将头文件和实现文件分开。我特别关注对局部变量T*的引用,以及如何正确使用sizeof() 在文件T.h中: class T {

我试图将一个类从“普通”类转换为模板类,但我不理解正确的语法。下面是一个(大大简化的)示例,我从中开始。这是VisualStudio 2010,C++,针对X64架构,Windows 7。 目标是将类T重写为模板,以处理TEntry或新类OtherTEntry,其概念类似于TEntry,具有相同的成员函数,但具有不同的数据成员

我很感激你给我的建议。如果可能的话,我希望将头文件和实现文件分开。我特别关注对局部变量T*的引用,以及如何正确使用sizeof()

在文件T.h中:

class T
{
    T(void);
    T(G *pGIn, const unsigned long s, char nIn);
    ~T(void);

    // Member functions
    public:
    bool Expand(const unsigned long newS);
    void Empty(void);

    private:
    G *pG;
    char n;
    unsigned long s;
    int f;
    TEntry *p;
};
在TEntry.h文件中:

class TEntry
{
    // Constructors
    public:
    TEntry();
    TEntry(int l);

    // Member functions
    public:
    void Relocate(int delta);

private:

    // Data members
    int k;
    TEntry *p;
};
在文件T.cpp中:

T::T()
{
    p=NULL; s=0; pG=NULL;
    Empty();
    return;
}

T::T(G *pGIn, const unsigned long m, char nIn)
{
    pG=pG; n=nIn;
    return;
}

T::~T(void)
{
    if(p!=NULL)
        delete[] p;
    return;
}

bool T::Expand(const unsigned long newS)
{
    T *pBefore=p;
    p=(T *)_realloc_dbg(p, newS*sizeof(T), _NORMAL_BLOCK,__FILE__,__LINE__);
    s=newS;
    return p!=NULL;
}

void T::Empty()
{
    f=0;
    return;
}
在TEntry.cpp文件中:

T::T()
{
}

T::T(int i)
{
    k=i;
}

void T::Relocate(int delta)
{
    k+=delta;
    return;
}
我希望将头文件和实现文件分开

虽然有可能做到这一点,但这有点像一场噩梦。通常最好将模板的所有部分放在一起

您可能想要的是这样的:

template< typename TYPE > class T
{
    // ...
    TYPE* p;
};
templateclass T
{
// ...
*p型;
};
然后可以使用
sizeof(TYPE)

有一件事你不能做,也永远不应该做的就是将realloc与new和delete混合。C++不支持重新分配新的和删除的内存。相反,它有一些容器,比如为您管理内存的
std::vector


而且,如前所述,一个字母的类和变量名称不是一个好主意。:)

最简单的方法是从一个完整的、有效的、非模板版本的
T
开始,该版本是按照您以后希望在模板中使用的类型之一编写的(这里的明显选择是:
TEntry

一旦有了一个工作的实现,就可以将其转换为模板

  • 为模板参数选择一个名称。类型参数的常用名称是T,但该名称已在项目中使用,因此我将使用
    U
  • 用模板参数的名称(
    U
    )替换
    T
    中出现的所有
    TEntry
  • 将模板标题添加到
    T
    的类定义中:

    template <class U>
    class T {
      //...
    
  • 确保所有模板代码都在头文件中(直接或通过
    #include
    指令间接)。模板不支持单独编译头文件和源文件

  • 通常,最好将模板代码保存在.h文件中。如果绝对必要,可以将实现放在.cpp文件中,有关详细信息,请参阅第6章

    你可以这样做(减少不太重要的细节):

    模板
    你的班级
    {
    YourClass()
    :p(空)、s(0)、pG(空)
    {
    空();
    }
    YourClass(G*pGIn,常量无符号长s,字符nIn)
    {
    //…在这里执行
    }
    ~YourClass()
    {
    如果(p!=NULL)
    删除p;
    }
    公众:
    bool Expand(const unsigned long newS)
    {
    T*pBefore=p;
    p=(T*)realloc\u dbg(p,newS*sizeof(T),\u NORMAL\u BLOCK,\uuuuuuuuu文件,\uuuuuuuu行);
    s=新闻;
    返回p!=NULL;
    }
    私人:
    G*pG;
    字符n;
    无符号长s;
    int f;
    T*p;
    };
    
    几点注意:

    • 将类模板命名为
      T
      确实是个坏主意,因为使用
      T
      作为模板参数名称是一种常见做法
    • 关于
      sizeof
      ,在您的代码示例中,它不应用于模板,而是应用于普通类,无论如何,在类、类模板或模板参数上使用
      sizeof
      应该不会有任何问题

    调用类T是一个非常糟糕的选择。请发布您尝试过的内容,在不显示时很难判断您做错了什么。是否有任何理由不使用
    std::vector
    ?请放心,我的实际类并没有命名为T。我现在有一对完整的工作类,但我只显示了代码的一小部分,足以询问我的问题我必须检查一下ReLoCo的用法。在VisualStudio中,“new”操作符使用Maloc。不管它可能在内部使用什么,也可能不在内部使用。你不能安全地混合C(MalcC/ReloLC/Free)和C++(new /Delphi)。内存分配策略。混合使用它们有什么不安全之处?在这种情况下,可移植性不是问题。谢谢你,这个评论非常有用。我已经有了T和TEntry的工作实现。至于“单独编译”,这不是我的目标,只是单独的文件。#include的作用是将头文件与实现文件结合起来。
    template <class U>
    «return type» T<U>::«member specification» //...
    
    template <class T>
    class YourClass
    {
        YourClass()
           : p(NULL), s(0), pG(NULL)
        {
           Empty();
        }
    
        YourClass(G *pGIn, const unsigned long s, char nIn)
        {
           // ... implementation here
        }
        ~YourClass()
        {
            if(p!=NULL)
               delete p;
        }
    
    
    public:
        bool Expand(const unsigned long newS)
        {
            T *pBefore=p;
            p=(T *)_realloc_dbg(p, newS*sizeof(T), _NORMAL_BLOCK,__FILE__,__LINE__);
            s=newS;
            return p!=NULL;
        }
    
    
    private:
        G *pG;
        char n;
        unsigned long s;
        int f;
        T* p;
    };