将C++类转换为模板类

Converting a C++ class to a template class

本文关键字:转换 C++      更新时间:2023-10-16

我刚刚创建完我的二进制树类,却意识到我应该把它作为一个模板。我已经花了几个小时试图将其转换为模板,但我不断收到大量错误,从"模板名称的无效使用"到"成员的额外资格"。我对模板的概念很陌生,但我对自己想要实现的目标有一个想法。

BTree.cpp

#include <iostream>
#include <string>
#include "BTree.h"
using namespace std;
BTree::BTree(board startboard, string startplayer)
    {
    treeboard = startboard;
    player = startplayer;
    root = new BTNode(treeboard, player,-1,-1);
    }

BTree::~BTree()
    {
    delete root;
    }
int BTree::sumtree()
    {
    if (root->getvalue(-1) > root->getvalue(1))
        return root->getchildposition(-1);
    else
        return root->getchildposition(1);
    }

BTree.h

#include <string>
#include "BTNode.h"
#include "board.h"
using namespace std;
class BTree
{
public:
    BTree(board startboard, string startplayer);
    ~BTree();
    int sumtree();
private:
    string player;
    board treeboard;
    BTNode *root;
};

"startplayer"当前是一个字符串,我希望它是通用模板类型。

我应该如何将其转换为单个模板文件?

好吧,让我们首先看看您的代码有哪些错误或其他缺陷:

  • 您的BTree有一个自定义dtor,因为它包含资源。但你违反了三条规则:
    您至少需要定义或删除您的赋值运算符和复制ctor
    作为替代(优选),将BTNode *root;更改为使用std::unique_ptr
  • 实现文件中包含的第一件事应该始终是它自己的头,以便在头中找到损坏的依赖关系
  • 标头应该包括使用它所必需的一切,而不是一点点

现在,有充分的理由说明为什么模板通常只使用头:

编译器需要定义来实例化它。
利用这个机会将一些函数移到类中。

接下来,您定义一个模板,如下所示:

template<class T> class BTree {
    int BTree::sumtree();
};

像这样的非内联成员:

template<class T> int BTree<T>::sumtree() {
    return //...
}

在模板中,可以像使用普通类型一样使用类型参数。

关于BTNode的一个注意事项:它是BTree的一个实现细节,因此将其定义放入类中(这使得模板化它变得相同,使用它也更容易)
或者,如果您实际上也不需要BTNode的所有模板参数(或者希望共享其实现),请单独对其进行模板化
不过,不要忘记更改BTree中的所有引用。

首先要在C++中使用模板,所有可执行代码都需要在.h文件中,以便在编译时可用。

然后模板化你的类,通常的方法是让它像:

template<class T>
class BTree
{
  Btree(T startPlayer)
  {
       player = startPlayer;
  }
  // ... snip ...
  T player;
}