首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将“普通”C++类转换为模板?

如何将“普通”C++类转换为模板?
EN

Stack Overflow用户
提问于 2013-02-24 07:57:58
回答 3查看 8.5K关注 0票数 0

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

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

我希望能就如何做这件事提出建议。如果可能的话,我希望将头文件和实现文件分开。我特别关注对局部变量T *的引用,以及如何正确地使用sizeof()。

在档案中T.h:

代码语言:javascript
复制
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中:

代码语言:javascript
复制
class TEntry
{
    // Constructors
    public:
    TEntry();
    TEntry(int l);

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

private:

    // Data members
    int k;
    TEntry *p;
};

在文件T.cpp中:

代码语言:javascript
复制
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中:

代码语言:javascript
复制
T::T()
{
}

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

void T::Relocate(int delta)
{
    k+=delta;
    return;
}
EN

回答 3

Stack Overflow用户

发布于 2013-02-24 08:34:00

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

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

  1. 为模板参数选择一个名称。类型参数的通常名称是T,但是这个名称已经在您的项目中使用了,所以我将使用U
  2. 用模板参数( TEntry )的名称替换T中所有出现的U
  3. 将模板头添加到T的类定义中: 模板类T{//.
  4. 将模板头添加到在类定义之外定义的T的每个成员: 模板返回类型T::成员规范//.
  5. 确保所有模板代码都在头文件中(直接或间接地通过#include指令)。模板不支持单独编译标头和源。
票数 1
EN

Stack Overflow用户

发布于 2013-02-24 08:31:46

我想把头文件和实现文件分开。

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

你可能想要的是这样的东西:

代码语言:javascript
复制
template< typename TYPE > class T
{
    // ...
    TYPE* p;
};

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

有一件事你不能做,也永远不应该做,那就是把realloc和new和delete混为一谈。C++不支持重新分配用new和delete分配的内存。相反,它有像std::vector这样的容器来为您管理内存。

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

票数 0
EN

Stack Overflow用户

发布于 2013-02-24 15:53:47

通常,最好将模板代码保存在.h文件中。如果绝对有必要,可以将实现放在.cpp文件中,有关详细信息,请参阅C++模板:大卫·凡夫奉约德和尼科莱·M·乔苏蒂斯的完整指南,Chaprer 6。

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

代码语言:javascript
复制
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不会有任何问题。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15049795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档