Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/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++;宣言 模板 类节点 {...}; int main { 节点*ptr; ptr=新节点; }_C++_Class_Templates_Pointers_Declaration - Fatal编程技术网

C++ 模板类指针c++;宣言 模板 类节点 {...}; int main { 节点*ptr; ptr=新节点; }

C++ 模板类指针c++;宣言 模板 类节点 {...}; int main { 节点*ptr; ptr=新节点; },c++,class,templates,pointers,declaration,C++,Class,Templates,Pointers,Declaration,如果编译失败,我必须将指针声明为 template <typename T> class Node {...}; int main { Node* ptr; ptr = new Node<int>; } Node*ptr; 为什么我必须在声明指针时指定类型我还没有创建类,为什么编译器必须知道它将指向什么类型。是不是不可能创建一个泛型指针,然后决定我想给它分配什么类型。 每当你在C++中创建任何类型的对象(包括指针)时,必须知道对象的完整类型。代码中没

如果编译失败,我必须将指针声明为

template <typename T>
class Node
{...};

int main
{
    Node* ptr;
    ptr = new Node<int>;
}
Node*ptr;

为什么我必须在声明指针时指定类型我还没有创建类,为什么编译器必须知道它将指向什么类型。是不是不可能创建一个泛型指针,然后决定我想给它分配什么类型。

每当你在C++中创建任何类型的对象(包括指针)时,必须知道对象的完整类型。代码中没有节点的类型,因此无法创建指向它的指针实例。您需要重新考虑如何设计和编写代码。

模板化在编译时解析类型。将新的
节点
对象指定给它时,指针必须在编译时知道它的确切类型

Node
Node
在二进制文件中可能会有很大的不同(对象的二进制布局会根据模板参数完全改变),因此将未解析的指针类型指向模板没有任何意义

您应该首先为节点定义一个公共父类:

Node<int>* ptr;
类节点库
{ ... }
模板
类节点:公共节点库
{
...
};
节点库*ptr;

简单的答案是C++使用(相当)严格的静态类型。 检查<代码>节点
是与
节点
完全无关的类型, 当编译器看到
ptr->doSomething()
时,它必须知道 调用
Node::doSomething()
Node::doSomething()

如果您确实需要某种动态通用性,那么 实际类型
ptr
将指向仅在运行时已知的,您需要 定义一个基类,并从中派生。(这是一个相当普遍的现象 类模板从非模板基派生的习惯用法 这样就可以在运行时解析指针中的通用性。)

为什么我必须在声明指针时指定类型我还没有创建类,为什么编译器必须知道它将指向什么类型

你可以用指针做很多事情,只需列出几个:

  • 根据指针的类型调用多个函数之一
  • 索引(假设它指向此类对象的连续数组中的第一个元素)
  • 获取指向的对象的大小
  • 将其传递给指针类型为参数的模板
为了让编译器生成高效执行这些操作的代码,它需要知道指针的类型。如果它推迟决策直到看到指针的类型,那么它需要:

  • 为指针以后可能采用的每种类型编译高效代码(生成一个非常臃肿的程序),或者
  • 创建低效代码,通过一些最坏情况下的悲观笨拙行为处理所有可能的类型,或者
  • 将自己的一个拷贝(编译器)嵌入到C++程序中,这样当它得到必要的信息时,它就可以完成它的工作,这会使每个琐碎的程序变得庞大(缓慢)
不可能创建一个泛型指针,然后决定要分配给它的类型

有点。。。您有很多选择:

  • 使用一个
    void*
    ,但是在它能够有意义地再次对指向的类型进行操作之前,您需要手动将其转换回该类型:在您的情况下,这意味着在某个地方记录它的内容,然后为每种可能使用单独的代码
  • 使用
    boost::any
    -非常类似于
    void*
    ,但具有内置的安全性
  • 使用
    boost::variant
    -更安全、更方便,但创建指针时必须列出可能的指向类型
  • 使用运行时多态对象族和虚拟分派。。。这是经典的面向对象编程。。。您有一个指向“abstract”
    节点的指针,该节点声明了用于在任何特定类型的节点上操作的共享函数和成员数据,然后模板化的
    节点
    类派生自该abstract
    节点
    ,并实现函数的特定类型版本。然后使用
    virtual
    函数通过指向基类的指针调用这些函数

正如尼尔·巴特沃斯(Neil Butterworth)和吕克·丹顿(Luc Danton)所指出的那样,您不能拥有Node*类型的指针,因为Node不是一种类型。它是一个模板。是的,Node是一个类模板,但是这里的类只是限定了模板的类型。一种方法是:正如类和类的实例是非常不同的东西一样,模板和模板实例化也是如此。正是这些模板实例化(例如节点)才是类。类模板是另一种野兽。

到目前为止,它还没有出现在任何答案中,我认为它不值得写一个,但这里有一点很重要:
Node
不是一种类型。它是一个模板。的确,这是一个类模板,但只有像
节点
节点
节点
这样的东西才是类型<代码>节点
将永远是一个模板,并且只有指向类型的指针。没有指向模板的指针这样的东西。这一点非常重要,它应该出现在答案中,而不仅仅是注释中。正确的语法不应该是
Node*ptr=new Node()?我想
()
应该在场。@热心的极客optional@Mike,你设法重写了我的完整答案。您确定这是您的意图吗?我所做的只是在
节点
节点
周围添加反勾号,以将它们格式化为代码而不是文本。如果没有这种格式,读“节点和节点可以非常不同”的句子就没有意义了。@Yola,我不太清楚你在这里的意思是什么?问题
class NodeBase
{ ... }

template<typename ValueT>
  class Node : public NodeBase
{
 ...
};

NodeBase* ptr;