Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++_Templates - Fatal编程技术网

C++ 转换C++;类转换为模板类

C++ 转换C++;类转换为模板类,c++,templates,C++,Templates,我刚刚创建完我的二叉树类,却意识到我应该把它作为一个模板。我现在花了几个小时试图将其转换为模板,但我不断收到大量错误,从“模板名称的无效使用”到“成员的额外资格”。我对模板的概念是陌生的,但我对我要实现的目标有一个想法 BTree.cpp #包括 #包括 #包括“BTree.h” 使用名称空间std; BTree::BTree(船上右舷侧、字符串右舷侧) { 树板=起始板; 玩家=起始玩家; 根=新的BTNode(树板,玩家,-1,-1); } BTree::~BTree() { 删除根; }

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

BTree.cpp

#包括
#包括
#包括“BTree.h”
使用名称空间std;
BTree::BTree(船上右舷侧、字符串右舷侧)
{
树板=起始板;
玩家=起始玩家;
根=新的BTNode(树板,玩家,-1,-1);
}
BTree::~BTree()
{
删除根;
}
int BTree::sumtree()
{
如果(根->获取值(-1)>根->获取值(1))
返回根->getchildposition(-1);
其他的
返回根->getchildposition(1);
}
BTree.h

#包括
#包括“BTNode.h”
#包括“board.h”
使用名称空间std;
B类树
{
公众:
BTree(船上右板、串式右板);
~b树();
int sumtree();
私人:
弦乐演奏者;
木板;
BTNode*根;
};
“startplayer”当前是一个字符串,我希望它是通用模板类型


我的过程应该是什么?把它变成一个模板文件?

首先,在C++中使用模板,所有的可执行代码都需要在.h文件中,这样编译时就可以使用。 然后,要对类进行模板化,通常的方法是如下所示:

template<class T>
class BTree
{
  Btree(T startPlayer)
  {
       player = startPlayer;
  }
  // ... snip ...
  T player;
}
模板
B类树
{
Btree(T起始层)
{
玩家=起始玩家;
}
//…剪断。。。
T-player;
}

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

  • 您的
    BTree
    有一个自定义dtor,因为它包含资源。但是你违反了3条规则:
    您至少需要定义或删除赋值运算符和复制运算符。
    作为替代方案(优选),更改
    BTNode*root
    使用
    std::unique\u ptr
  • 实现文件中包含的第一件事应该始终是它自己的头,以便在头中查找已断开的依赖项
  • 标题应该包括使用它所必需的所有内容,而不是更多
现在,有很好的理由解释为什么模板通常只包含标题:

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

接下来,定义如下所示的模板:

template<class T> class BTree {
    int BTree::sumtree();
};
template<class T> int BTree<T>::sumtree() {
    return //...
}
模板类BTree{
int BTree::sumtree();
};
非内联成员如下所示:

template<class T> class BTree {
    int BTree::sumtree();
};
template<class T> int BTree<T>::sumtree() {
    return //...
}
template int BTree::sumtree(){
返回/。。。
}
在模板中,可以像使用普通类型一样使用类型参数

关于
BTNode
:这是
BTree
的一个实现细节,因此将它的定义放入类中(这使得模板化它和使用它一样容易)。
或者,如果您实际上并不需要
BTNode
的所有模板参数(或想要共享其实现),请单独对其进行模板化。

不过,不要忘了更改
BTree
中的所有引用。

首先实现这个非模板时不要感到不舒服。这叫做提升。创建一个只在
int
string
上工作的类,并使其正常工作,然后取出通用表单,通常会更容易。为什么要在构造函数中复制startboard和startplayer两次?@NeilKirk在我戏剧性地更改类时留下的代码,没有意识到这些行现在是多余的;谢谢你的提醒,我是否正确地实施了这一点?我在编译@Matt时遇到了这个错误:您仍然有我列出的所有错误和缺陷。“g++main.o board.o board.h BTNode.o BTNode.h BTree.h-o test”您不应该编译.h文件好的,注意到。如何编译模板;我以为它应该在头球里?是的。在将使用BTree的文件中,只要包含“BTree.h”,代码就会正确生成。请您详细说明一下“std::unique\u ptr”,我不明白我是如何错误地使用这个指针的。@Matt:我不是说您使用的指针是错误的,我是说隐式定义的复制构造函数和赋值运算符对您来说是错误的。是一个智能指针,它将简化处理内存分配和释放。(允许您删除dtor并遵循零规则。)