QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1924|回复: 18

g++无法编译通过但是VC6编译通过的程序,请各位指教

[复制链接]
发表于 2004-4-24 02:19:14 | 显示全部楼层 |阅读模式
请问这是什么问题(代码如下):
下面是  node.h 的代码:
#ifndef Node_
#define Node_

template <class T> class LinkedStack;
template <class T> class LinkedQueue;

template <class T>
class Node {
   friend LinkedStack<T>;
   friend LinkedQueue<T>;
   friend ostream& operator<<
          (ostream&, const LinkedStack<T>&);
   friend istream& operator>>
          (istream&, LinkedStack<T>&);
   friend ostream& operator<<
          (ostream&, const LinkedQueue<T>&);
   friend istream& operator>>
          (istream&, LinkedQueue<T>&);
   private:
      T data;
      Node<T> *link;
};

#endif
-------------------------------------------
下面是xcept.h的代码(for VC):
/ exception classes for various error types

#ifndef Xcept_
#define Xcept_

#include <new.h>

// bad initializers
class BadInitializers {
   public:
      BadInitializers() {}
};

// insufficient memory
class NoMem {
   public:
      NoMem() {}
};

// change new to throw NoMem instead of standard behavior
// Visual C++ requires following form of my_new_handler
int my_new_handler(size_t x)
{
   throw NoMem();
   // even though the following statement is unreachable,
   // visual C++ will not compile successfully without it
   return 0;
};

_PNH Old_Handler_ = _set_new_handler(my_new_handler);

// improper array, find, insert, or delete index
// or deletion from empty structure
class OutOfBounds {
   public:
      OutOfBounds() {}
};

// use when operands should have matching size
class SizeMismatch {
   public:
      SizeMismatch() {}
};

// use when zero was expected
class MustBeZero {
   public:
      MustBeZero() {}
};

// use when zero was expected
class BadInput {
   public:
      BadInput() {}
};

#endif
----------------------------------------------------------------------------
下面是xcept.h的代码(for gnu):
// exception classes for various error types

#ifndef Xcept_
#define Xcept_

//#include <except.h>
#include <new.h>

// bad initializers
class BadInitializers {
   public:
      BadInitializers() {}
};

// insufficient memory
class NoMem {
   public:
      NoMem() {}
};

// change new to throw NoMem instead of xalloc
void my_new_handler()
{
   throw NoMem();
};

new_handler Old_Handler_ = set_new_handler(my_new_handler);

// improper array, find, insert, or delete index
// or deletion from empty structure
class OutOfBounds {
   public:
      OutOfBounds() {}
};

// use when operands should have matching size
class SizeMismatch {
   public:
      SizeMismatch() {}
};

// use when zero was expected
class MustBeZero {
   public:
      MustBeZero() {}
};

// use when zero was expected
class BadInput {
   public:
      BadInput() {}
};

#endif


------------------------------------------------------------------------------
下面是lqueue.h的代码:
// header file lqueue.h
// linked queue

#ifndef LinkedQueue_
#define LinkedQueue_
#include <iostream.h>
#include "node.h"
#include "xcept.h"

template<class T>
class LinkedQueue {
// FIFO objects
     friend ostream& operator<<(ostream&, const LinkedQueue<T>&);
     friend istream& operator>>(istream&, LinkedQueue<T>&);
   public:
      LinkedQueue() {front = rear = 0;} // constructor
      ~LinkedQueue(); // destructor
      bool IsEmpty() const
           {return ((front) ? false : true);}
      bool IsFull() const;
      T First() const; // return first element
      T Last() const; // return last element
      LinkedQueue<T>& Add(const T& x);
      LinkedQueue<T>& Delete(T& x);
      int Size() const;
   private:
      Node<T> *front;  // pointer to first node
      Node<T> *rear;   // pointer to last node
      void Erase();    // delete all nodes
};

template<class T>
LinkedQueue<T>::~LinkedQueue()
{// Queue destructor.  Delete all nodes.
   Node<T> *next;
   while (front) {
      next = front->link;
      delete front;
      front = next;
      }
}

template<class T>
bool LinkedQueue<T>::IsFull() const
{// Is the queue full?
   Node<T> *p;
   try {p = new Node<T>;
        delete p;
        return false;}
   catch (NoMem) {return true;}
}

template<class T>
T LinkedQueue<T>::First() const
{// Return first element of queue.  Throw
// OutOfBounds exception if the queue is empty.
   if (IsEmpty()) throw OutOfBounds();
   return front->data;
}

template<class T>
T LinkedQueue<T>::Last() const
{// Return last element of queue.  Throw
// OutOfBounds exception if the queue is empty.
   if (IsEmpty()) throw OutOfBounds();
   return rear->data;
}

template<class T>
LinkedQueue<T>& LinkedQueue<T>::Add(const T& x)
{// Add x to rear of queue.  Do not catch
// possible NoMem exception thrown by new.

   // create node for new element
   Node<T> *p = new Node<T>;
   p->data = x;
   p->link = 0;

   // add new node to rear of queue
   if (front) rear->link = p;  // queue not empty
   else front = p;             // queue empty
   rear = p;

   return *this;
}

template<class T>
LinkedQueue<T>& LinkedQueue<T>::Delete(T& x)
{// Delete first element and put it in x.  Throw
// OutOfBounds exception if the queue is empty.

   if (IsEmpty()) throw OutOfBounds();

   // save element in first node
   x = front->data;

   // delete first node
   Node<T> *p = front;
   front = front->link;
   delete p;

   return *this;
}

template<class T>
void LinkedQueue<T>::Erase()
{// Delete all nodes.

   Node<T> *next;

   while (front) {
      next = front->link;
      delete front;
      front = next;
      }
}

template<class T>
int LinkedQueue<T>::Size() const
{// Return number of elements in the queue.

   int size = 0;
   Node<T> *current = front;
   while (current) {
      size++;
      current = current->link;
      }

      return size;
}

// overload >>
template<class T>
istream& operator>>(istream& in, LinkedQueue<T>& q)
{// Input queue q from front to rear.
   // first delete all elements from q

   q.Erase();

   // determine size of input queue
   int size;
   cout << "Enter size of queue" << endl;
   in >> size;

   if (!size) // no elements
      return in;

   // at least one element to input
   // input the queue elements and link together
   cout << "Enter the elements from front to rear"
        << endl;

   // get first element
   q.rear = q.front = new Node<T>;
   in >> q.front->data;

   // get remaining elements
   for (int i = 2; i <= size ; i++) {
      q.rear->link = new Node<T>;
      q.rear = q.rear->link;
      in >> q.rear->data;
      }

   // set pointer in rear node
   q.rear->link = 0;

   return in;
}

// overload <<
template <class T>
ostream& operator<<(ostream& out,const LinkedQueue<T>& q)
{// Output the queue q from front to rear
// output queue size

   int size = q.Size();
   out << "The queue has " << size
       << " element(s)" << endl;

   // output queue elements
   out << "The element(s) from front to rear are"
       << endl;

   Node<T> *current = q.front;
   for (int i = 1; i <= size ; i++) {
      out << current->data << ' ';
      current = current->link;
      }
   out << endl;

   return out;
}


#endif
------------------------------
下面是lqueue.cpp的代码:
#include"lqueue.h"

int main()
{
    LinkedQueue<int> Q;
    cin>>Q;
    cout<<Q;

    return 1;
}
发表于 2004-4-24 19:36:40 | 显示全部楼层
我狂晕!
回复

使用道具 举报

发表于 2004-4-24 21:18:11 | 显示全部楼层
这么长。。。还没有缩进 。。。
回复

使用道具 举报

发表于 2004-4-24 21:38:37 | 显示全部楼层
贴一下g++的出错信息
回复

使用道具 举报

发表于 2004-4-24 23:05:45 | 显示全部楼层
写的不够标准
回复

使用道具 举报

 楼主| 发表于 2004-4-24 23:59:17 | 显示全部楼层
原来是有缩进的,贴上去就没有了。再贴一次。顺便说明一下程序。
这个程序是数据结构里的一个队列(queue),用链表方式实现。
node.h是队列节点(类)的声明与实现,node.h同时也是另一个数据结构堆栈(stack)的节点,
lqueue.h是队列LinkedQueue(LinkedQueue同时也是模板类)的声明与实现,lqueue.cpp主要是队列(类)的一个实例,用于测试重载的运算符 << 和 >> 能不能正常工作,运算符重载函数是

LinkedQueue的友元函数:
friend ostream& operator<<(ostream&, const LinkedQueue<T>&);
  
friend istream& operator>>(istream&, LinkedQueue<T>&);

xcept.h是用于异常处理,VC和GNU下的有所不同,编译中这里没有出错,不过也贴上来。

用g++编译出错都是在于运算符重符,如果不要lqueue.cpp中的两句(如下),可以通过编译:

cin>>Q;
cout<<Q;
回复

使用道具 举报

发表于 2004-4-25 00:00:14 | 显示全部楼层
[code:1]
[code]
your code here
[/code]
[/code:1]
回复

使用道具 举报

 楼主| 发表于 2004-4-25 00:01:26 | 显示全部楼层
这个是node.h的代码:
[code:1]

#ifndef Node_
#define Node_

template <class T> class LinkedStack;
template <class T> class LinkedQueue;

template <class T>
class Node {
   friend LinkedStack<T>;
   friend LinkedQueue<T>;
   friend ostream& operator<<
          (ostream&, const LinkedStack<T>&);
   friend istream& operator>>
          (istream&, LinkedStack<T>&);
   friend ostream& operator<<
          (ostream&, const LinkedQueue<T>&);
   friend istream& operator>>
          (istream&, LinkedQueue<T>&);
   private:
      T data;
      Node<T> *link;
};

#endif

[/code:1]
回复

使用道具 举报

 楼主| 发表于 2004-4-25 00:02:38 | 显示全部楼层
这个是lqueue.h的代码:
[code:1]
// header file lqueue.h
// linked queue

#ifndef LinkedQueue_
#define LinkedQueue_
#include <iostream.h>
#include "node.h"
#include "xcept.h"

template<class T>
class LinkedQueue {
// FIFO objects
     friend ostream& operator<<(ostream&, const LinkedQueue<T>&);
     friend istream& operator>>(istream&, LinkedQueue<T>&);
   public:
      LinkedQueue() {front = rear = 0;} // constructor
      ~LinkedQueue(); // destructor
      bool IsEmpty() const
           {return ((front) ? false : true);}
      bool IsFull() const;
      T First() const; // return first element
      T Last() const; // return last element
      LinkedQueue<T>& Add(const T& x);
      LinkedQueue<T>& Delete(T& x);
      int Size() const;
   private:
      Node<T> *front;  // pointer to first node
      Node<T> *rear;   // pointer to last node
      void Erase();    // delete all nodes
};

template<class T>
LinkedQueue<T>::~LinkedQueue()
{// Queue destructor.  Delete all nodes.
   Node<T> *next;
   while (front) {
      next = front->link;
      delete front;
      front = next;
      }
}

template<class T>
bool LinkedQueue<T>::IsFull() const
{// Is the queue full?
   Node<T> *p;
   try {p = new Node<T>;
        delete p;
        return false;}
   catch (NoMem) {return true;}
}

template<class T>
T LinkedQueue<T>::First() const
{// Return first element of queue.  Throw
// OutOfBounds exception if the queue is empty.
   if (IsEmpty()) throw OutOfBounds();
   return front->data;
}

template<class T>
T LinkedQueue<T>::Last() const
{// Return last element of queue.  Throw
// OutOfBounds exception if the queue is empty.
   if (IsEmpty()) throw OutOfBounds();
   return rear->data;
}

template<class T>
LinkedQueue<T>& LinkedQueue<T>::Add(const T& x)
{// Add x to rear of queue.  Do not catch
// possible NoMem exception thrown by new.

   // create node for new element
   Node<T> *p = new Node<T>;
   p->data = x;
   p->link = 0;

   // add new node to rear of queue
   if (front) rear->link = p;  // queue not empty
   else front = p;             // queue empty
   rear = p;

   return *this;
}

template<class T>
LinkedQueue<T>& LinkedQueue<T>::Delete(T& x)
{// Delete first element and put it in x.  Throw
// OutOfBounds exception if the queue is empty.

   if (IsEmpty()) throw OutOfBounds();

   // save element in first node
   x = front->data;

   // delete first node
   Node<T> *p = front;
   front = front->link;
   delete p;

   return *this;
}

template<class T>
void LinkedQueue<T>::Erase()
{// Delete all nodes.

   Node<T> *next;

   while (front) {
      next = front->link;
      delete front;
      front = next;
      }
}

template<class T>
int LinkedQueue<T>::Size() const
{// Return number of elements in the queue.

   int size = 0;
   Node<T> *current = front;
   while (current) {
      size++;
      current = current->link;
      }

      return size;
}

// overload >>
template<class T>
istream& operator>>(istream& in, LinkedQueue<T>& q)
{// Input queue q from front to rear.
   // first delete all elements from q

   q.Erase();

   // determine size of input queue
   int size;
   cout << "Enter size of queue" << endl;
   in >> size;

   if (!size) // no elements
      return in;

   // at least one element to input
   // input the queue elements and link together
   cout << "Enter the elements from front to rear"
        << endl;

   // get first element
   q.rear = q.front = new Node<T>;
   in >> q.front->data;

   // get remaining elements
   for (int i = 2; i <= size ; i++) {
      q.rear->link = new Node<T>;
      q.rear = q.rear->link;
      in >> q.rear->data;
      }

   // set pointer in rear node
   q.rear->link = 0;

   return in;
}

// overload <<
template <class T>
ostream& operator<<(ostream& out,const LinkedQueue<T>& q)
{// Output the queue q from front to rear
// output queue size

   int size = q.Size();
   out << "The queue has " << size
       << " element(s)" << endl;

   // output queue elements
   out << "The element(s) from front to rear are"
       << endl;

   Node<T> *current = q.front;
   for (int i = 1; i <= size ; i++) {
      out << current->data << ' ';
      current = current->link;
      }
   out << endl;

   return out;
}


#endif


[/code:1]
回复

使用道具 举报

 楼主| 发表于 2004-4-25 00:03:58 | 显示全部楼层
这是lqueue.cpp的代码:
[code:1]
#include"lqueue.h"

int main()
{
    LinkedQueue<int> Q;
    cin>>Q;
    cout<<Q;

    return 1;
}


[/code:1]
回复

使用道具 举报

 楼主| 发表于 2004-4-25 00:07:00 | 显示全部楼层
这个是gnu下的xcept.h
[code:1]

// exception classes for various error types

#ifndef Xcept_
#define Xcept_

//#include <except.h>
#include <new.h>

// bad initializers
class BadInitializers {
   public:
      BadInitializers() {}
};

// insufficient memory
class NoMem {
   public:
      NoMem() {}
};

// change new to throw NoMem instead of xalloc
void my_new_handler()
{
   throw NoMem();
};

new_handler Old_Handler_ = set_new_handler(my_new_handler);

// improper array, find, insert, or delete index
// or deletion from empty structure
class OutOfBounds {
   public:
      OutOfBounds() {}
};

// use when operands should have matching size
class SizeMismatch {
   public:
      SizeMismatch() {}
};

// use when zero was expected
class MustBeZero {
   public:
      MustBeZero() {}
};

// use when zero was expected
class BadInput {
   public:
      BadInput() {}
};

#endif

[/code:1]
回复

使用道具 举报

 楼主| 发表于 2004-4-25 00:08:17 | 显示全部楼层
这个VC下的xcept.h
[code:1]
// exception classes for various error types

#ifndef Xcept_
#define Xcept_

#include <new.h>

// bad initializers
class BadInitializers {
   public:
      BadInitializers() {}
};

// insufficient memory
class NoMem {
   public:
      NoMem() {}
};

// change new to throw NoMem instead of standard behavior
// Visual C++ requires following form of my_new_handler
int my_new_handler(size_t x)
{
   throw NoMem();
   // even though the following statement is unreachable,
   // visual C++ will not compile successfully without it
   return 0;
};

_PNH Old_Handler_ = _set_new_handler(my_new_handler);

// improper array, find, insert, or delete index
// or deletion from empty structure
class OutOfBounds {
   public:
      OutOfBounds() {}
};

// use when operands should have matching size
class SizeMismatch {
   public:
      SizeMismatch() {}
};

// use when zero was expected
class MustBeZero {
   public:
      MustBeZero() {}
};

// use when zero was expected
class BadInput {
   public:
      BadInput() {}
};

#endif

[/code:1]
回复

使用道具 举报

 楼主| 发表于 2004-4-25 00:23:53 | 显示全部楼层
g++的出错信息:

[code:1]
[root@bing linkedqueue]# ls
lqueue.cpp  lqueue.h  node.h  xcept.h
[root@bing linkedqueue]# g++ -o queue.o lqueue.cpp
In file included from /usr/include/c++/3.3.2/backward/iostream.h:31,
                 from lqueue.h:6,
                 from lqueue.cpp:1:
/usr/include/c++/3.3.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <sstream> instead of the deprecated header <strstream.h>. To disable this warning use -Wno-deprecated.
In file included from lqueue.h:7,
                 from lqueue.cpp:1:
node.h:10: error: friend declaration requires class-key, i.e. `friend struct
   LinkedStack<T>'
node.h:11: error: friend declaration requires class-key, i.e. `friend struct
   LinkedQueue<T>'
node.h:13: warning: friend declaration `std::ostream& operator<<(std::ostream&,
   const LinkedStack<T>&)' declares a non-template function
node.h:13: warning: (if this is not what you intended, make sure the function
   template has already been declared and add <> after the function name here)
   -Wno-non-template-friend disables this warning
node.h:15: warning: friend declaration `std::istream& operator>>(std::istream&,
   LinkedStack<T>&)' declares a non-template function
node.h:17: warning: friend declaration `std::ostream& operator<<(std::ostream&,
   const LinkedQueue<T>&)' declares a non-template function
node.h:19: warning: friend declaration `std::istream& operator>>(std::istream&,
   LinkedQueue<T>&)' declares a non-template function
In file included from lqueue.cpp:1:
lqueue.h:13: warning: friend declaration `std::ostream&
   operator<<(std::ostream&, const LinkedQueue<T>&)' declares a non-template
   function
lqueue.h:14: warning: friend declaration `std::istream&
   operator>>(std::istream&, LinkedQueue<T>&)' declares a non-template function
[root@bing linkedqueue]#


[/code:1]
回复

使用道具 举报

发表于 2004-4-26 14:23:48 | 显示全部楼层

主要是名字空间的和模板函数申明的问题。改好的代码如下:

lqueue.cpp
[code:1]#include"lqueue.h"

int main()
{
    LinkedQueue<int> Q;
    std::cin>>Q;
    std::cout<<Q;

    return 1;
}
[/code:1]
回复

使用道具 举报

发表于 2004-4-26 14:25:44 | 显示全部楼层
[code:1]#ifndef Node_
#define Node_

template <class T> class LinkedStack;
template <class T> class LinkedQueue;

template <class T>
class Node {
   friend class LinkedStack<T>;
   friend class LinkedQueue<T>;
   template <class S> friend std::ostream& operator<<
          (std::ostream&, const LinkedStack<S>&);
   template <class S> friend std::istream& operator>>
          (std::istream&, LinkedStack<S>&);
   template <class S> friend std::ostream& operator<<
          (std::ostream&, const LinkedQueue<S>&);
   template <class S> friend std::istream& operator>>
          (std::istream&, LinkedQueue<S>&);
   private:
      T data;
      Node<T> *link;
};

#endif[/code:1]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-8 11:59 , Processed in 0.095801 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表