【问题标题】:c++ Having trouble implementing templated nested classc++ 在实现模板化嵌套类时遇到问题
【发布时间】:2019-10-27 04:31:07
【问题描述】:

编辑:添加了更多代码/附加文件以及编译错误 所以我很难弄清楚如何为我的嵌套类实现构造函数。 这是我的 .h 文件

//--------------------------------------------------------------------
//
//  StackArray.h
//
//  Class declaration for the array implementation of the Stack ADT
//
//--------------------------------------------------------------------

#ifndef STACKARRAY_H
#define STACKARRAY_H

#include <stdexcept>
#include <iostream>

using namespace std;

#include "Stack.h"

template <typename DataType>
class StackLinked : public Stack<DataType> {

  public:

    StackLinked(int maxNumber = Stack<DataType>::MAX_STACK_SIZE);
    StackLinked(const StackLinked& other);
    StackLinked& operator=(const StackLinked& other);
    ~StackLinked();

    void push(const DataType& newDataItem) throw (logic_error);
    DataType pop() throw (logic_error);

    void clear();

    bool isEmpty() const;
    bool isFull() const;

    void showStructure() const;

  private:

    class StackNode {
      public:
    StackNode(const DataType& nodeData, StackNode* nextPtr);

    DataType dataItem;
    StackNode* next;
    };

    StackNode* top;
};

#endif      //#ifndef STACKARRAY_H

和我的 .cpp 的一部分(让我慢慢发疯的部分)

#include "StackLinked.h"
#include <iostream>
using namespace std;

template<class DataType>
StackLinked<DataType>::StackNode<DataType>::StackNode(const DataType& nodeData, StackNode* nextPtr)
{
  dataItem = nodeData;
  next = nextPtr;
}
template<class DataType>
StackLinked<DataType>::StackLinked(int maxNumber)
{
  top = nullptr;
}
template<class DataType>
StackLinked<DataType>::StackLinked(const StackLinked& other)
{
  StackNode<DataType>* old = other.top;
  if(isEmpty())
    top = nullptr;
  else{
    top = new StackNode<DataType>;
    top->dataItem = old->dataItem;

    StackNode<DataType>* newPtr = top;
    while(old != nullptr)
    {
      old = old->next;
      DataType nextItem = old->dataItem;
      StackNode<DataType>* temp = new StackNode<DataType>;
      temp->dataItem = nextItem;
      newPtr->next = temp;
      newPtr = newPtr->next;
    }
    newPtr->next = nullptr;
  }
}
template<class DataType>
StackLinked<DataType>::~StackLinked()
{
  clear();
}
template<class DataType>
StackLinked<DataType>& StackLinked<DataType>::operator=(const StackLinked& other)
{
  if(this != &other)
  {
    while(top != nullptr)
    {
      StackNode<DataType>* nodePtr = top;
      top = top->next;
      delete nodePtr;
    }
    top = nullptr;
    top = new StackNode<DataType>;
    top->dataItem = other->dataItem;

    StackNode<DataType>* newPtr = top;
    while(other != nullptr)
    {
      other = other->next;
      DataType nextItem = other->dataItem;
      StackNode<DataType>* temp = new StackNode<DataType>;
      temp->dataItem = nextItem;
      newPtr->next = temp;
      newPtr = newPtr->next;
    }
    newPtr->next = nullptr;
  }
  return *this;
}
template<class DataType>
void StackLinked<DataType>::push(const DataType& newDataItem) throw (logic_error)
{
  if(top == nullptr)
  {
    top = new StackNode<DataType>;
    top->dataItem = newDataItem;
  }
  else
  {
    StackNode<DataType> nodePtr = new StackNode<DataType>;
    nodePtr->next = top;
    nodePtr->data = newDataItem;
    top = nodePtr;
  }
}
template<class DataType>
DataType StackLinked<DataType>::pop() throw (logic_error)
{
  if(isEmpty())
  {
    throw logic_error("Empty Stack");
  }
  else
  {
    StackNode<DataType> nodePtr = new StackNode<DataType>;
    nodePtr = top;
    top = top->next;
    DataType anItem = nodePtr->dataItem;
    delete nodePtr;
    return anItem;
  }
}
template<class DataType>
void StackLinked<DataType>::clear()
{
  while(top != nullptr)
  {
    StackNode<DataType>* nodePtr = top;
    top = top->next;
    delete nodePtr;
  }
}
template<class DataType>
bool StackLinked<DataType>::isEmpty() const
{
  return top == nullptr;
}
template<class DataType>
bool StackLinked<DataType>::isFull() const
{
  return false;
}

这是一个作业,并且提供了头文件以及一些其他文件,并且无法修改。在此之前我从未见过/尝试过嵌套类,并且在尝试查找有关该主题的相关信息时遇到了一些真正的困难。我发现的所有内容都在非模板类上,尽管它应该非常相似,和/或没有解释如何在单独的文件中实现它。从我所看到的,我的尝试是在正确的方向,但还没有能够得到它编译。我试过了

class StackLinked<DataType>::StackNode<DataType>(const DataType& nodeData, StackNode* nextPtr)
class StackLinked<DataType>::StackNode(const DataType& nodeData, StackNode* nextPtr)
class StackLinked<DataType>::StackNode::StackNode(const DataType& nodeData, StackNode* nextPtr)
StackNode::StackNode(const DataType& nodeData, StackNode* nextPtr)
StackLinked::StackNode(const DataType& nodeData, StackNode* nextPtr)

还有一大堆我想不出来的其他人。如果有人能找出我的错误并向我解释,我将不胜感激。提前致谢! 我也包括了 stack.h 文件,其他文件是主文件和配置文件。

//--------------------------------------------------------------------
//
//   Stack.h
// 
//  Class declaration of the abstract class interface to be used as
//  the basis for implementations of the Stack ADT.
//
//--------------------------------------------------------------------

#ifndef STACK_H
#define STACK_H

#include <stdexcept>
#include <iostream>

using namespace std;

template <typename DataType>
class Stack {
  public:
    static const int MAX_STACK_SIZE = 8;

    virtual ~Stack();

    virtual void push(const DataType& newDataItem) throw (logic_error) = 0;
    virtual DataType pop() throw (logic_error) = 0;

    virtual void clear() = 0;

    virtual bool isEmpty() const = 0;
    virtual bool isFull() const = 0;

    virtual void showStructure() const = 0;
};

template <typename DataType>
Stack<DataType>::~Stack() 
// Not worth having a separate class implementation file for the destuctor
{}

#endif      // #ifndef STACK_H

这些是我从原始代码中得到的错误:

sleer@DESKTOP-96LGT1D:/mnt/c/Users/steph/Desktop/cs302/projects/proj1/cs302-hw2-code-package$ g++ StackLinked.cpp StackLinked.h Stack.h
StackLinked.cpp:6:24: error: non-template ‘StackNode’ used as template
 StackLinked<DataType>::StackNode<DataType>::StackNode(const DataType& nodeData, StackNode* nextPtr)
                        ^~~~~~~~~
StackLinked.cpp:6:24: note: use ‘StackLinked<DataType>::template StackNode’ to indicate that it is a template
StackLinked.cpp:6:1: error: need ‘typename’ before ‘StackLinked<DataType>::StackNode’ because ‘StackLinked<DataType>’ is a dependent scope
 StackLinked<DataType>::StackNode<DataType>::StackNode(const DataType& nodeData, StackNode* nextPtr)
 ^~~~~~~~~~~~~~~~~~~~~
In file included from StackLinked.h:17:0:
Stack.h:25:52: warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
     virtual void push(const DataType& newDataItem) throw (logic_error) = 0;
                                                    ^~~~~
Stack.h:26:28: warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
     virtual DataType pop() throw (logic_error) = 0;
                            ^~~~~
StackLinked.h:29:44: warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
     void push(const DataType& newDataItem) throw (logic_error);
                                            ^~~~~
StackLinked.h:30:20: warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
     DataType pop() throw (logic_error);
                    ^~~~~
Stack.h:25:52: warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
     virtual void push(const DataType& newDataItem) throw (logic_error) = 0;
                                                    ^~~~~
Stack.h:26:28: warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
     virtual DataType pop() throw (logic_error) = 0;
                            ^~~~~

以下是我根据不均匀标记的建议得到的错误

sleer@DESKTOP-96LGT1D:/mnt/c/Users/steph/Desktop/cs302/projects/proj1/cs302-hw2-code-package$ g++ StackLinked.cpp StackLinked.h
StackLinked.cpp: In copy constructor ‘StackLinked<DataType>::StackLinked(const StackLinked<DataType>&)’:
StackLinked.cpp:19:3: error: ‘StackLinked<DataType>::StackNode’ is not a template
   StackNode<DataType>* old = other.top;
   ^~~~~~~~~
StackLinked.cpp:23:15: error: ‘StackLinked<DataType>::StackNode’ is not a template
     top = new StackNode<DataType>;
               ^~~~~~~~~
StackLinked.cpp:26:5: error: ‘StackLinked<DataType>::StackNode’ is not a template
     StackNode<DataType>* newPtr = top;
     ^~~~~~~~~
StackLinked.cpp:31:7: error: ‘StackLinked<DataType>::StackNode’ is not a template
       StackNode<DataType>* temp = new StackNode<DataType>;
       ^~~~~~~~~
StackLinked.cpp:31:39: error: ‘StackLinked<DataType>::StackNode’ is not a template
       StackNode<DataType>* temp = new StackNode<DataType>;
                                       ^~~~~~~~~
StackLinked.cpp: In member function ‘StackLinked<DataType>& StackLinked<DataType>::operator=(const StackLinked<DataType>&)’:
StackLinked.cpp:51:7: error: ‘StackLinked<DataType>::StackNode’ is not a template
       StackNode<DataType>* nodePtr = top;
       ^~~~~~~~~
StackLinked.cpp:56:15: error: ‘StackLinked<DataType>::StackNode’ is not a template
     top = new StackNode<DataType>;
               ^~~~~~~~~
StackLinked.cpp:59:5: error: ‘StackLinked<DataType>::StackNode’ is not a template
     StackNode<DataType>* newPtr = top;
     ^~~~~~~~~
StackLinked.cpp:64:7: error: ‘StackLinked<DataType>::StackNode’ is not a template
       StackNode<DataType>* temp = new StackNode<DataType>;
       ^~~~~~~~~
StackLinked.cpp:64:39: error: ‘StackLinked<DataType>::StackNode’ is not a template
       StackNode<DataType>* temp = new StackNode<DataType>;
                                       ^~~~~~~~~
StackLinked.cpp: At global scope:
StackLinked.cpp:74:63: warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
 void StackLinked<DataType>::push(const DataType& newDataItem) throw (logic_error)
                                                               ^~~~~
StackLinked.cpp: In member function ‘void StackLinked<DataType>::push(const DataType&)’:
StackLinked.cpp:78:15: error: ‘StackLinked<DataType>::StackNode’ is not a template
     top = new StackNode<DataType>;
               ^~~~~~~~~
StackLinked.cpp:83:5: error: ‘StackLinked<DataType>::StackNode’ is not a template
     StackNode<DataType> nodePtr = new StackNode<DataType>;
     ^~~~~~~~~
StackLinked.cpp:83:39: error: ‘StackLinked<DataType>::StackNode’ is not a template
     StackNode<DataType> nodePtr = new StackNode<DataType>;
                                       ^~~~~~~~~
StackLinked.cpp: At global scope:
StackLinked.cpp:90:39: warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
 DataType StackLinked<DataType>::pop() throw (logic_error)
                                       ^~~~~
StackLinked.cpp: In member function ‘DataType StackLinked<DataType>::pop()’:
StackLinked.cpp:98:5: error: ‘StackLinked<DataType>::StackNode’ is not a template
     StackNode<DataType> nodePtr = new StackNode<DataType>;
     ^~~~~~~~~
StackLinked.cpp:98:39: error: ‘StackLinked<DataType>::StackNode’ is not a template
     StackNode<DataType> nodePtr = new StackNode<DataType>;
                                       ^~~~~~~~~
StackLinked.cpp: In member function ‘void StackLinked<DataType>::clear()’:
StackLinked.cpp:111:5: error: ‘StackLinked<DataType>::StackNode’ is not a template
     StackNode<DataType>* nodePtr = top;
     ^~~~~~~~~
In file included from StackLinked.h:17:0:
Stack.h:25:52: warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
     virtual void push(const DataType& newDataItem) throw (logic_error) = 0;
                                                    ^~~~~
Stack.h:26:28: warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
     virtual DataType pop() throw (logic_error) = 0;
                            ^~~~~
StackLinked.h:29:44: warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
     void push(const DataType& newDataItem) throw (logic_error);
                                            ^~~~~
StackLinked.h:30:20: warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated]
     DataType pop() throw (logic_error);```

【问题讨论】:

  • 嵌套类唯一的特别之处是它们可以访问周围类的私有成员。
  • 模板通常应该在标题中实现,而不是在.cpp 文件中。请参阅this post 了解更多信息。
  • 如果您遇到错误,您需要发布一个minimal reproducible example,其中包括您的源文件和完整的具体错误。
  • 我偷偷怀疑出了什么问题,但作为记录,您可以edit your question 并复制并粘贴您得到的编译器错误吗?这将帮助我或多或少地确定。
  • @n.m.和 Chipster,我添加了与该项目相关的源文件以及完整的 .cpp 和与我发布的内容相关的错误以及下面的建议。超级 这是迄今为止我们在课堂上一直这样做的方式,这也是我这样写的原因。我将查看您的建议以尝试了解更多信息。感谢大家的帮助!我显然是在这里提出问题的新手,因此对于我的问题或其他问题的任何帮助将不胜感激。

标签: c++ templates constructor inner-classes implementation


【解决方案1】:
template<class DataType>
StackLinked<DataType>::StackNode::StackNode(const DataType& nodeData, StackNode* nextPtr)

template&lt;class DataType&gt; 引入了一个名为DataType 的模板参数,它可以是任意类型。

StackLinked&lt;DataType&gt; 指的是StackLinked 的特化,DataType 作为模板参数。

StackLinked&lt;DataType&gt;::StackNode 指的是StackLinked&lt;DataType&gt; 内的嵌套类StackNode,它不是 类模板,因此它不会获取任何模板参数列表 (&lt;...&gt;)。

StackLinked&lt;DataType&gt;::StackNode::StackNode 指的是StackNodeStackLinked&lt;DataType&gt; 内部的构造函数。

其余的是与您在类定义中的声明相匹配的参数列表。

也就是说,正如 cmets 中提到的,类模板成员函数(以及它们的嵌套类的成员函数)的定义通常需要放在头文件中。

【讨论】:

  • 感谢您的回答,但您的建议仍然会导致我的错误。我已经添加了更多代码以及我为您的建议和我最初发布的内容而得到的错误。再次感谢。
  • @StephenLeer 不,我建议作为构造函数定义的介绍的代码不再产生任何错误。这些错误消息来自您之前未显示且未询问的无关代码。但所有这些与我在这个答案中解释的原因相同:StackNode 不是类模板,它只是一个类。因此它没有任何模板参数列表(由&lt;&gt; 包围的东西)。所以,例如,StackNode&lt;DataType&gt;* old = other.top; 是错误的。
  • AHHHHHHHHHHH 非常感谢!整个项目让我在对模板和嵌套类的理解不均衡之间产生了如此大的转变。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多