从头文件调用函数

时间:2015-03-19 19:40:08

标签: c++ scope

家庭作业
我试图从我的三个头文件中的每一个调用我的main函数中的两个函数。

#ifndef UNSORTEDPQ_H
#define UNSORTEDPQ_H

#include <exception>
#include <cstddef>
#include <cmath>
using namespace std;

template <class Type>
class UnsortedPQ
{
private:
struct DLLNode {
    Type data;
    DLLNode *prev;
    DLLNode *next;
};

DLLNode *head, *tail, *node;

public:
void insertUPQ ( Type data ){
  DLLNode *newnode = new DLLNode;
  newnode -> node = data;
  newnode -> prev = NULL;
  if (isEmpty()){
      newnode -> next = NULL;
      head = tail = newnode;
  } 
  else {
      newnode -> next = NULL;
      newnode -> prev = node -> prev -> next;
      tail = newnode;
  }
 }

 // removes and returns the minimum value in the queue
 // throws an exception if the queue is empty
 Type removeUPQ ( void ) throw(exception){
  if (isEmpty()) {
      exception("Can't dequeue empty Priority Queue");
  }

  Type min = head -> data;

  // special case: queue has one element
  if (size()==1){
      while (head != NULL) {
          DLLNode *next = head -> next;
          delete head;
          head = next;
      }
      return min;
  }

  // determine minimum element
  for (node = head; node != NULL; node = node -> next){
      if (node -> data < min) {
          min = node -> data;
      }
  }
  // special case: queue has two elements
  if (size()==2){
      if (head -> data== min){
          delete head;
          tail -> previous = NULL;
          head = tail;
      } 
      else {
          delete tail;
          head -> next = NULL;
          tail = head;
      }
      return min;
  }

  // remove element and update next and previous for elements around it
  for (node = head; node != NULL; node = node -> next){
      if (node -> data == min){
          // special case if min elem is head
          if (node == head){
              DLLNode*oldHead=head;
              head = head -> next;
              head -> prev = NULL;
              delete oldHead;
              return min;
          }
          // special case if min elem is tail
          if(node == tail){
              DLLNode*oldTail=tail;
              tail = tail-> prev;
              tail -> next = NULL;
              delete oldTail;
              return min;
          }
          // for cases where min elem is not head or tail
          DLLNode *prevNode = node -> prev;
          DLLNode *nextNode = node -> next;
          prevNode -> next = node -> next;
          nextNode -> prev = node -> prev;
          delete node;
          return min;
      }
}

#ifndef SORTEDPQ_H
#define SORTEDPQ_H

#include <exception>
#include <cstddef>
#include <cmath>
using namespace std;

template <class Type>
class SortedPQ
{
private:
    struct DLLNode {
        Type data;
        DLLNode *prev;
        DLLNode *next;
    };

    DLLNode *head, *tail, *node;


public:

// inserts a piece of data into the priority queue
void insertSPQ ( Type data ){
DLLNode curr = head;
while(curr != tail && node -> data <= curr -> data){
    curr = curr -> next;
}
DLLNode tempCurr = curr;
node -> next = tempCurr;
node -> prev = tempCurr -> prev;
tempCurr -> prev -> next = node;
tempCurr -> prev = node;
}
// removes and returns the minimum value in the queue
// throws an exception if the queue is empty
Type removeSPQ ( void ) throw(exception){
 if (isEmpty()) {
    exception("Can't dequeue an empty Priority Queue");
}
Type min = head -> node;
if (node == head){
    DLLNode*oldHead=head;
    head = head -> next;
    head -> prev = NULL;
    delete oldHead;
    return min;
}

#ifndef HEAPPQ_H
#define HEAPPQ_H

#include <exception>
#include <cstddef>
#include <cmath>
using namespace std;

template <class Type>
class HeapPQ
{
private:
    Type *data;
    Type heapSize;
    Type arraySize;
    Type floor(Type arg);
    Type getLChildIndex(Type nodeIndex){
        return 2 * nodeIndex + 1;
    } 

    Type getRightChildIndex(Type nodeIndex){
        return 2 * nodeIndex + 2;
    }

    Type getParentIndex(Type nodeIndex){
        return floor((nodeIndex - 1) / 2);
    }

    public:   
    void HeapPropertyInsert(Type nodeIndex){
    Type parentIndex, tmp;
    if(nodeIndex != 0){
        parentIndex = getParentIndex(nodeIndex);
        if(data[parentIndex] > data[nodeIndex]){
            tmp = data[parentIndex];
        data[parentIndex] = data[nodeIndex];
        data[nodeIndex] = tmp;
        HeapPropertyInsert(parentIndex);
        }
    }
   }

   // inserts a piece of data into the priority queue
   void insertHPQ ( Type data ) throw(exception){
    if (heapSize == arraySize){
        exception ("Cannot insert, heap is full");
    }
    else{
        heapSize++;
        data[heapSize - 1] = data;
        HeapPropertyInsert(heapSize - 1);
    }
   }

   void HeapPropertyRemove(Type nodeIndex){
    Type leftChildIndex, rightChildIndex, minIndex, tmp;
    leftChildIndex = getLChildIndex(nodeIndex);
    rightChildIndex = getRightChildIndex(nodeIndex);
    if(rightChildIndex >= heapSize){
        if(leftChildIndex >= heapSize)
            return;
        else
            minIndex = leftChildIndex;
    }
    else{
        if (data[leftChildIndex] < data[rightChildIndex])
            minIndex = leftChildIndex;
        else
            minIndex = rightChildIndex;
    }
    if(data[nodeIndex] > data[minIndex]){
        tmp = data[minIndex];
        data[minIndex] = data[nodeIndex];
        data[nodeIndex] = tmp;
        HeapPropertyRemove(minIndex);
    }
   }

   // removes and returns the minimum value in the queue
   // throws an exception if the queue is empty
   Type removeHPQ ( void ) throw(exception){
    if(isEmpty())
        exception("Cannot remove, heap is empty");
    else{
        data[0] = data[heapSize - 1];
        heapSize--;
        if(heapSize > 0)
            HeapPropertyRemove(0);
    }
   } 

我的main.cpp:

#include "UnsortedPQ.h"
#include "SortedPQ.h"
#include "HeapPQ.h"
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdlib>

using namespace std;
int main(){

int choice;
int elem;
int array_size = 1024;
char * array = new char[array_size];
int position = 0;

ifstream fin("numbers.txt");
if(fin.is_open()){
    cout << "File opened successfully." << endl;
    while(!fin.eof() && position < array_size){
        fin.get(array[position]);
        position++;
    }
    array[0] = choice;
    switch (choice){
        case '0': //UnsortedPQ
            for(int i = 2; array[i]; i++ ){
                insertUPQ(array[i]); <----- error
                removeUPQ(array[i]); <----- error
            }
            break;
        case '1': //SortedPQ    
            for(int i = 2; array[i]; i++ ){
                insertSPQ(array[i]); <----- error
                removeSPQ(array[i]); <----- error
            }
            break;
        case '2':// HeapPQ  
            for(int i = 2; array[i]; i++ ){
                insertHPQ(array[i]); <----- error
                removeHPQ(array[i]); <----- error
            }
            break;
    }
}
else{
    cout << "File could not be opened." << endl;
}
return 0;
}

我一直收到编译器错误,声明这些函数“未在此范围内声明”。我认为既然包含了头文件并且函数是公共的,我可以在main.cpp的任何地方随意调用它们。再次,这是家庭作业,所以我不是在寻找快速解决方案,但是一些建议或正确方向的观点将非常受欢迎。

2 个答案:

答案 0 :(得分:2)

您尝试调用的所有函数是属于特定方法。要使用这些方法,您必须创建特定对象

char * array = new char[array_size];

UnsortedPQ<char> Object;

Object.insertUPQ(array[i]);

教程的链接解释了C ++中究竟是什么类,如何创建它们并使用它们:

http://www.cplusplus.com/doc/tutorial/classes/

答案 1 :(得分:0)

此代码存在很多问题。如果不解决各个功能实现的问题,则需要修复以下错误:

  1. 如果没有该类的实例,则无法调用类方法。因此,要调用方法insertSPQ,您必须拥有SortedPQ类。你可以创建一个这样的:
  2. SortedPQ<char> *spq = new SortedPQ<char>;

    然后调用这个函数:

    spq->insertSPQ(array[i]);


    1. 您正在使用错误的签名调用函数。例如,您尝试调用
    2. spq->removeSPQ(array[i]);

      (在我添加了spq类实例之后),但该函数的参数被定义为void,如下所示:

      Type removeSPQ(void) throw(exception){

      所以你的排序条件看起来应该更像:

          case '1': //SortedPQ    
              SortedPQ<char> *spq = new SortedPQ<char>;
      
              for (int i = 2; array[i]; i++){
                  spq->insertSPQ(array[i]);
                  spq->removeSPQ(array[i]);
              }
              break;
      

      当然,这并没有真正解决所有问题,因为你仍然需要从spq中释放内存。

      另外,正如另一位评论者指出的那样,你错过了#endif。这些应该是每个头文件的最后一行,以关闭您的初始#ifndef

      最后,将类实现和声明放在同一个头文件中通常被认为是一种不好的做法。通常最好有一个.h文件用于声明,一个单独的.cpp用于实际实现。它应该按原样运作,而不是最佳实践。