0

我正在尝试将一个类从“普通”类转换为模板类,但我不理解正确的语法。下面是我开始的一个(非常简化的)示例。这是 Visual Studio 2010,C++,针对 x64 架构,Windows 7。

目标是将类 T 重写为模板来处理 TEntry 或新类 OtherTEntry,在概念上类似于 TEntry,具有相同的成员函数,但具有不同的数据成员。

我很感激关于如何最好地做到这一点的建议。如果可能的话,我想将头文件和实现文件分开。我特别关注对局部变量 T * 的引用,以及如何正确使用 sizeof()。

在文件 Th 中:

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;
}
4

3 回答 3

1

最简单的方法是从一个完整的、工作的、非模板版本开始,T它是根据您以后要在模板中使用的一种类型编写的(这里的明显选择:)TEntry

一旦你有了一个有效的实现,你就可以将它转换为一个模板。

  1. 为您的模板参数选择一个名称。类型参数的常用名称是 T,但该名称已在您的项目中使用,因此我将使用U.
  2. 用模板参数的名称替换所有出现的TEntryinside ( )TU
  3. 将模板头添加到类定义中T

    template <class U>
    class T {
      //...
    
  4. T将模板头添加到在类定义之外定义的每个成员:

    template <class U>
    «return type» T<U>::«member specification» //...
    
  5. 确保所有模板代码都在头文件中(直接或间接通过#include指令。模板不支持单独编译头文件和源代码。
于 2013-02-24T08:34:00.450 回答
0

我想将头文件和实现文件分开

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

你可能想要的是这样的:

template< typename TYPE > class T
{
    // ...
    TYPE* p;
};

然后您可以使用sizeof( TYPE ).

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

而且,正如已经提到的,一个字母的类和变量名称不是一个好主意。:)

于 2013-02-24T08:31:46.393 回答
0

一般来说,最好将模板代码保存在 .h 文件中。如果绝对必要,可以将实现放在 .cpp 文件中,请参阅C++ 模板:David Vandevoorde 和 Nicolai M. Josuttis 的完整指南,第 6 章,了解详细信息。

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

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;
};

几点注意事项:

  • 命名您的类模板T确实是个坏主意,因为使用T模板参数名称是一种常见的做法。
  • 关于sizeof,在您的代码示例中,它没有应用于模板,而是应用于普通类,无论如何,sizeof在类、类模板或模板参数上使用应该没有任何问题。
于 2013-02-24T15:53:47.403 回答