1

我在链接类实现中重载了'<<'运算符,我在主函数中声明了.cpp文件,但它不起作用,并且发生此错误: 未定义对运算符<&列表的引用)

这是linkedlist.h文件中ostream函数的声明:

  friend std::ostream& operator<< (std::ostream& os, LinkedList<T>& list);

这是 ostream 函数的实现:

 template <typename T>
   std::ostream& operator<< (std::ostream& os, LinkedList<T> list) 
 {
  list.current = list.start;
  while(list.current != NULL)
    {
        os<< list.current->info<<" -> ";
        list.current = list.current->next;
    }
    os<<"NULL"<<endl;
    return os;
 }

在主函数中,我创建了一个包含来自 SavingAccount 类的对象的列表

LinkedList <SavingAccount> list;

并且错误发生在这一行的主函数中:

 cout << list <<endl;

好吧..这是 LinkedList 类的实现:

#include "LinkedList.h"
#include "SavingAccount.h"
#include <cstddef>
using namespace std;

template <typename T>
LinkedList<T>::LinkedList()
{
   start = NULL;
   current = NULL;
}
template <typename T>
LinkedList<T>::~LinkedList()
  {
    // Add code.
  }

  template <typename T>
   std::ostream& operator<< (std::ostream& os,const LinkedList<T>& list) {
    list.current = list.start;
    while(list.current != NULL)
    {
        os<< list.current->info<<" -> ";
        list.current = list.current->next;
    }
    os<<"NULL"<<endl;
    return os;
  }

这是 LinkedLins 类的头文件:

#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include<iostream>

using namespace std;


template <typename T>
struct Node{
    T info;
    Node<T> *next;
};

template <typename T>

class LinkedList
{
    Node<T> *start;
    Node<T> *current;
public:
    LinkedList();
    ~LinkedList();
    friend std::ostream& operator<< (std::ostream& os, const LinkedList<T>& list);

  };

#endif // LINKEDLIST_H

我希望你们能帮助我,非常感谢你们的帮助


SQL Server 存储过程在出错时不返回选择结果

我有一个非常简单的 SP,如下所示:

BEGIN

SET @CUR_IO_GB = @IO_GB
SET @CUR_TOTDATE = @TOTDATE
SET @CUR_TOT_NO = @TOT_NO
SET @CUR_TOT_NO_SEQ = @TOT_NO_SEQ
SET @CUR_CUS_CD = @CUS_CD
SET @CUR_MAT_CD = @MAT_CD
SET @CUR_JCOLOR = @JCOLOR
SET @CUR_CANCEL_YN = @CANCEL_YN
SET @CUR_CREQTY = @CREQTY

SELECT  @ERR_MSG    = 2
PRINT 'INSERTING'
INSERT  INTO    LC_OUT_REQUEST_DETAIL(IO_GB, TOTDATE, TOT_NO, TOT_NO_SEQ, 
                LOCCD, ALLOC_QTY, OUT_QTY, IN_EMP, IN_DATE, UP_EMP, UP_DATE,
                CUS_CD, MAT_CD, JCOLOR, CANCEL_YN, DELIVERY_YN, OUT_YN, JDANGA)
VALUES('021', '20130817',  '000001', '000001', 
    'A0021', 2, 2, 'BATCH4', GETDATE(), 'BATCH4', GETDATE(),
    '0001031080', '41183', '1090', '1','1', 'N', 15 )

PRINT @ERR_MSG
SELECT  @ERR_MSG    = 2
RETURN @ERR_MSG

END

出于测试目的,我故意尝试通过插入重复键来破坏上述存储过程,从而导致主键违规。

我的问题是,我期望 ERR_MSG 中的结果为 2,即使出现错误(例如,打印 @ERR_MSG 给我 2,但选择 @ERR_MSG = 2 然后返回它总是给我 null)。

这种行为的原因是什么?有什么方法可以让我在出错时仍然选择并返回所需的值?

4

3 回答 3

1

好的,在您发布代码之后,您的问题似乎是您LinkedList在头文件和源文件之间拆分模板声明和实现。除非您在源文件中进行显式实例化,否则您不能这样做:您不能将模板声明和实现分开,它们必须在一个标头中。

您需要将 LinkedList.cpp 的内容放在LinkedList.h,完全摆脱源文件,只需在需要的地方包含更新的标题。

constPS 另外,一般来说,通过引用修改对象并不是一个好主意。编译器不会喜欢它。您可能需要重新考虑您的设计。

PPS 如果您真的想要并且打算修改您通过const引用访问的类的对象中的某些数据成员,则需要将这些数据成员声明为mutable.

PPPS 详细说明foo模板类的模板函数友元声明bar,避免在注释中进行冗长的讨论。

如果您在类中定义此类函数及其声明,这是一件简单的事情 - 只需使用friend关键字。例如,friend void foo( bar< T > & ) { ... }

如果你在类外单独定义它,你需要在声明中使用稍微不同的语法并避免模板参数的阴影:(template< typename U > friend void foo( bar< U > & ) { ... }假设Ubar类声明的模板参数中没有使用)。然后你在类之外定义它。

如果你想为它指定默认模板参数,foo它会变得更加棘手。您不能在friend声明中使用默认模板参数,因此您必须转发声明所有内容:

template< typename T > class bar;

template< typename T = int >
void foo( bar< T > & );

template< typename T >
class bar
{
  template< typename U >
  friend void foo( bar< U > & );
};

template< typename T >
void foo( bar< T > & )
{
 ...
}

最后一个 PPPPS(我希望!)。由于您在 for 中使用foroperator <<类型SavingAccount,因此您也需要定义for 。operator <<LinkedListoperator <<SavingAccount

自我注意:不要在评论部分回答另一个答案;)。

于 2013-08-16T13:10:55.783 回答
1

我不确定这是否是导致错误的原因,但您的函数定义与您的函数声明不同:

// you left out a & (reference sign) - LinkedList<T>& list in declaration
std::ostream& operator<< (std::ostream& os, LinkedList<T> list) 

编辑

Petr Budnik是对的,您需要将模板实现保存在与定义相同的文件中。

他没有提到一件事(这可能会给您带来问题):您需要明确说明您在重载template T之上使用 a :<<

template < typename T>
friend std::ostream& operator<< (std::ostream& os, LinkedList<T>& list);

此外,const如果您打算修改LinkedList您传入的内容,请删除。

这是(大致)你的LinkedList.h样子:

template <typename T>
struct Node{
    T info;
    Node<T> *next;
};

template <typename T>
class LinkedList
{
    Node<T> *start;
    Node<T> *current;
public:
    LinkedList();
    ~LinkedList();

    template < typename T>
    friend std::ostream& operator<< (std::ostream& os, LinkedList<T>& list);


};

template <typename T>
LinkedList<T>::LinkedList()
{
    start = NULL;
    current = NULL;
}

template <typename T>
LinkedList<T>::~LinkedList()
{
    // Add code.
}

template <typename T>
std::ostream& operator<<(std::ostream& os, LinkedList<T>& list) {
    list.current = list.start;
    while (list.current != NULL)
    {
        os << list.current->info << " -> ";
        list.current = list.current->next;
    }
    os << "NULL" << endl;
    return os;
}    

附言

我可以建议您使用nullptr代替0orNULL吗?它是一种新的 C++11 语法,有一些好处(如果需要,请阅读它)。

希望这可以帮助!

于 2013-08-16T12:39:56.087 回答
0

除了非常病态的情况外,“输出”操作不应该改变要输出的值,所以正确的函数原型应该是

template<class T>
std::ostream& operator<<(std::ostream& s, const LinkedList<T>& list)
{
...
}

并且您不应为list成员分配新值(例如 in list.current = list.start)。你最好也重新考虑一下逻辑......

此外,模板功能必须在头文件中实现,而不是 cpp 文件

于 2013-08-16T12:45:28.010 回答